zr SaveNameChicago ExpressEpochTimej 4gDate11/12/2024 6:05:30 PMVersionNumberv13.3GameModeChicago ExpressGameTypeGameGameComplexityMedium ComplexityPlayingTime01<PlayerCounts01TagsB0 Board Games1Strategy Games2 Components3Rules4English5Wabash Cannonball6Bohrer7Winsome8Train9Trains10Shares11Stock12 Economic13Auction / Bidding14 Investment15Network16Route Building17 Cube RailsGravityà?PlayAreaà?Table Table_NoneSky Sky_MuseumNoteWTo rotate dials: click, hold, and then use the rotate buttons to rotate by 30 degrees TabStatesÞ1ntitleWhitebodycolorWhitevisibleColor&rð?gð?bð?id2ntitleBrownbodycolorBrownvisibleColor&r ZÜ?g€h‘Í?b€= ·?id3jtitleRedbodycolorRedvisibleColor&r Zdë?g ™™¹?b@b¸?id4ptitleOrangebodycolorOrangevisibleColor&r@�—î?g ‡Ù?b`‘í¼?id5ptitleYellowbodycolorYellowvisibleColor&r€Âõì?g€j¼ì?b Æ?id6ntitleGreenbodycolorGreenvisibleColor&rÀt“È?g€—næ?b �Å?id7ltitleBluebodycolorBluevisibleColor&r€?5¾?g€Âõà?bð?id8ltitleTealbodycolorTealvisibleColor&r`ƒÀ?g€?5æ?b@‹lã?id9ptitlePurplebodycolorPurplevisibleColor&r@bä?gÀ?b¬î?id 10ltitlePinkbodycolorPinkvisibleColor&ràQ¸î?g€“Ü?b ñÒé?id 11ntitleBlackbodycolorBlackvisibleColor&rÐ?gÐ?bÐ?id GridÔTypeLinesColor&rgbOpacityè?ThickLinesSnappingOffsetBothSnappingxSizeð?ySizeð?PosOffset&xyð?zLightingjLightIntensity ®Gá?LightColor&rð?gào_ï?bÀ„|ì?AmbientIntensityÀÌÌô?AmbientTypeAmbientSkyColor&rà?gà?bà?AmbientEquatorColor&rà?gà?bà?AmbientGroundColor&rà?gà?bà?ReflectionIntensityð?LutIndexLutContributionð?Hands*EnableDisableUnusedHidingComponentTagsÚlabelsÍ00displayedScorenormalizedscore10displayedSharenormalizedshare20displayedHousenormalizedhouse3&displayednormalized4&displayednormalized5&displayednormalized6&displayednormalized7&displayednormalized8&displayednormalized9&displayednormalized10&displayednormalized11&displayednormalized12&displayednormalized13&displayednormalized140displayedBoardnormalizedboard150displayedMoneynormalizedmoneyTurnspEnableTypeTurnOrderReverseSkipEmptyDisableInteractionsPassTurnsTurnColorDecalPalletLuaScriptA--[[ Lua code. See documentation: https://api.tabletopsimulator.com/ --]] --[[ The onLoad event is called after the game save finishes loading. --]] function onLoad() --[[ print('onLoad!') --]] end --[[ The onUpdate event is called once per frame. --]] function onUpdate() --[[ print('onUpdate loop!') --]] endLuaScriptStateXmlUIRSnapPointsE0MPosition&xI@y€phï?zÀìð@Tags0Board1MPosition&xI@y€phï?z€ÀTags0Board2MPosition&xÀóI@y€phï?z ‘ƒ6ÀTags0Board3MPosition&xÀSI@y€phï?z ¾x6@Tags0BoardObjectStates†a 02GUIDafc863NameCustom_AssetbundleTransform‰posXKÀposY$ÀposZ ™™5ÀrotX€Áî¥>rotY@Wù¾rotZ@K$оscaleXð?scaleYð?scaleZð?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomAssetbundleÚAssetbundleURLihttps://steamusercontent-a.akamaihd.net/ugc/879750610978795929/723C50F43FAB3DE3DC12CB8460536E8CB34B60A3/AssetbundleSecondaryURLMaterialIndexTypeIndexLoopingEffectIndexLuaScriptLuaScriptStateXmlUI12GUIDc8edcaNameCustom_AssetbundleTransform‰posXKÀposY$ÀposZ ™™5@rotX€Áî¥>rotY€V@rotZ@K$оscaleXð?scaleYð?scaleZð?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomAssetbundleÚAssetbundleURLihttps://steamusercontent-a.akamaihd.net/ugc/879750610978795929/723C50F43FAB3DE3DC12CB8460536E8CB34B60A3/AssetbundleSecondaryURLMaterialIndexTypeIndexLoopingEffectIndexLuaScriptLuaScriptStateXmlUI22GUID393bf7NameCustom_AssetbundleTransform‰posXK@posY$ÀposZ ™™5@rotX€Áî¥>rotY€f@rotZ@K$оscaleXð?scaleYð?scaleZð?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomAssetbundleÚAssetbundleURLihttps://steamusercontent-a.akamaihd.net/ugc/879750610978795929/723C50F43FAB3DE3DC12CB8460536E8CB34B60A3/AssetbundleSecondaryURLMaterialIndexTypeIndexLoopingEffectIndexLuaScriptLuaScriptStateXmlUI32GUID12c65eNameCustom_AssetbundleTransform‰posXK@posY$ÀposZ ™™5ÀrotX€Áî¥>rotYàp@rotZ@K$оscaleXð?scaleYð?scaleZð?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomAssetbundleÚAssetbundleURLihttps://steamusercontent-a.akamaihd.net/ugc/879750610978795929/723C50F43FAB3DE3DC12CB8460536E8CB34B60A3/AssetbundleSecondaryURLMaterialIndexTypeIndexLoopingEffectIndexLuaScriptLuaScriptStateXmlUI4DGUIDbd69bdNameChinese_Checkers_PieceTransform‰posX€=JR@posYô(ô¿posZ)ÜEÀrotX€b$_?rotY€f@rotZÀ…å8?scaleXàefú?scaleYàefú?scaleZàefú?NicknameFlex Table ControlDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsMaterialIndexLuaScriptÑ?tableHeightOffset = -9.5 function onSave() saved_data = JSON.encode({tid=tableImageData, cd=checkData}) --saved_data = "" return saved_data end function onload(saved_data) --Loads the tracking for if the game has started yet if saved_data ~= "" then local loaded_data = JSON.decode(saved_data) tableImageData = loaded_data.tid checkData = loaded_data.cd else tableImageData = {} checkData = {move=false, scale=false} end --Disables interactable status of objects with GUID in list for _, guid in ipairs(ref_noninteractable) do local obj = getObjectFromGUID(guid) if obj then obj.interactable = false end end --Establish references to table parts obj_leg1 = getObjectFromGUID("afc863") obj_leg2 = getObjectFromGUID("c8edca") obj_leg3 = getObjectFromGUID("393bf7") obj_leg4 = getObjectFromGUID("12c65e") obj_surface = getObjectFromGUID("4ee1f2") obj_side_top = getObjectFromGUID("35b95f") obj_side_bot = getObjectFromGUID("f938a2") obj_side_lef = getObjectFromGUID("9f95fd") obj_side_rig = getObjectFromGUID("5af8f2") controlActive = false createOpenCloseButton() end --Activation/deactivation of control panel --Activated by clicking on function click_toggleControl(_, color) if permissionCheck(color) then if not controlActive then --Activate control panel controlActive = true self.clearButtons() createOpenCloseButton() createSurfaceInput() createSurfaceButtons() createScaleInput() createScaleButtons() else --Deactivate control panel controlActive = false self.clearButtons() self.clearInputs() createOpenCloseButton() end end end --Table surface control --Changes table surface function click_applySurface(_, color) if permissionCheck(color) then updateSurface() broadcastToAll("New Table Image Applied", {0.2,0.9,0.2}) end end --Saves table surface function click_saveSurface(_, color) if permissionCheck(color) then local nickname = self.getInputs()[1].value local url = self.getInputs()[2].value if nickname == "" then --No nickname broadcastToAll("Please supply a nickname for this save.", {0.9,0.2,0.2}) else --Nickname exists if findInImageDataIndex(url, nickname) == nil then --Save doesn't exist already table.insert(tableImageData, {url=url, name=nickname}) broadcastToAll("Image URL saved to memory.", {0.2,0.9,0.2}) --Refresh buttons self.clearButtons() createOpenCloseButton() createSurfaceButtons() createScaleButtons() else --Save exists already broadcastToAll("Memory already contains a save with this Name or URL. Delete it first.", {0.9,0.2,0.2}) end end end end --Loads table surface function click_loadMemory(_, color, index) if permissionCheck(color) then self.editInput({index=0, value=tableImageData[index].name}) self.editInput({index=1, value=tableImageData[index].url}) updateSurface() broadcastToAll("Table Image Loaded", {0.2,0.9,0.2}) end end --Deletes table surface function click_deleteMemory(_, color, index) if permissionCheck(color) then table.remove(tableImageData, index) self.clearButtons() createOpenCloseButton() createSurfaceButtons() createScaleButtons() broadcastToAll("Element Removed from Memory", {0.2,0.9,0.2}) end end --Updates surface from the values in the input field function updateSurface() local customInfo = obj_surface.getCustomObject() customInfo.diffuse = self.getInputs()[2].value obj_surface.setCustomObject(customInfo) obj_surface = obj_surface.reload() end --Table Scale control --Applies Scale to table pieces function click_applyScale(_, color) if permissionCheck(color) then local newWidth = tonumber(self.getInputs()[3].value) local newDepth = tonumber(self.getInputs()[4].value) if type(newWidth) ~= "number" then broadcastToAll("Invalid Width", {0.9,0.2,0.2}) return elseif type(newDepth) ~= "number" then broadcastToAll("Invalid Depth", {0.9,0.2,0.2}) return elseif newWidth<0.1 or newDepth<0.1 then broadcastToAll("Scale cannot go below 0.1", {0.9,0.2,0.2}) return elseif newWidth>12 or newDepth>12 then broadcastToAll("Scale should not go over 12 (world size limitation)", {0.9,0.2,0.2}) return else changeTableScale(math.abs(newWidth), math.abs(newDepth)) broadcastToAll("Scale applied.", {0.2,0.9,0.2}) end end end --Checks/unchecks move box for hands function click_checkMove(_, color) if permissionCheck(color) then local find_func = function(o) return o.click_function=="click_checkMove" end if checkData.move == true then checkData.move = false local buttonEntry = findButton(self, find_func) self.editButton({index=buttonEntry.index, label=""}) else checkData.move = true local buttonEntry = findButton(self, find_func) self.editButton({index=buttonEntry.index, label=string.char(10008)}) end end end --Checks/unchecks scale box for hands --This button was disabled for technical reasons --[[ function click_checkScale(_, color) if permissionCheck(color) then local find_func = function(o) return o.click_function=="click_checkScale" end if checkData.scale == true then checkData.scale = false local buttonEntry = findButton(self, find_func) self.editButton({index=buttonEntry.index, label=""}) else checkData.scale = true local buttonEntry = findButton(self, find_func) self.editButton({index=buttonEntry.index, label=string.char(10008)}) end end end ]] --Alters scale of elements and moves them function changeTableScale(width, depth) --Scaling factors used to translate scale to position offset local width2pos = (width-1) * 18 local depth2pos = (depth-1) * 18 --Hand zone movement if checkData.move == true then for _, pc in ipairs(ref_playerColor) do if Player[pc].getHandCount() > 0 then moveHandZone(Player[pc], width2pos, depth2pos) end end end --Hand zone scaling --The button to enable this was disabled for technical reasons if checkData.scale == true then for _, pc in ipairs(ref_playerColor) do if Player[pc].getHandCount() > 0 then scaleHandZone(Player[pc], width, depth) end end end --Resizing table elements obj_side_top.setScale({width, 1, 1}) obj_side_bot.setScale({width, 1, 1}) obj_side_lef.setScale({depth, 1, 1}) obj_side_rig.setScale({depth, 1, 1}) obj_surface.setScale({width, 1, depth}) --Moving table elements to accomodate new scale obj_side_lef.setPosition({-width2pos,tableHeightOffset,0}) obj_side_rig.setPosition({ width2pos,tableHeightOffset,0}) obj_side_top.setPosition({0,tableHeightOffset, depth2pos}) obj_side_bot.setPosition({0,tableHeightOffset,-depth2pos}) obj_leg1.setPosition({-width2pos,tableHeightOffset-0.5,-depth2pos}) obj_leg2.setPosition({-width2pos,tableHeightOffset-0.5, depth2pos}) obj_leg3.setPosition({ width2pos,tableHeightOffset-0.5, depth2pos}) obj_leg4.setPosition({ width2pos,tableHeightOffset-0.5,-depth2pos}) self.setPosition(obj_leg4.positionToWorld({-22.12, 8.74,-19.16})) --Only enabled when changing tableHeightOffset obj_surface.setPosition({0,tableHeightOffset,0}) end --Move hand zone, p=player reference, facts are scaling factors function moveHandZone(p, width2pos, depth2pos) local widthX = obj_side_rig.getPosition().x local depthZ = obj_side_top.getPosition().z for i=1, p.getHandCount() do local handT = p.getHandTransform() local pos = handT.position local y = handT.rotation.y if y<45 or y>320 or y>135 and y<225 then if pos.z > 0 then pos.z = pos.z + depth2pos - depthZ else pos.z = pos.z - depth2pos + depthZ end else if pos.x > 0 then pos.x = pos.x + width2pos - widthX else pos.x = pos.x - width2pos + widthX end end --Only enabled when changing tableHeightOffset --pos.y = tableHeightOffset + 14 handT.position = pos p.setHandTransform(handT, i) end end ---Scales hand zones, p=player reference, facts are scaling factors function scaleHandZone(p, width, depth) local widthFact = width / obj_side_top.getScale().x local depthFact = depth / obj_side_lef.getScale().x for i=1, p.getHandCount() do local handT = p.getHandTransform() local scale = handT.scale local y = handT.rotation.y if y<45 or y>320 or y>135 and y<225 then scale.x = scale.x * widthFact else scale.x = scale.x * depthFact end handT.scale = scale p.setHandTransform(handT, i) end end --Information gathering --Checks if a color is promoted or host function permissionCheck(color) if Player[color].host==true or Player[color].promoted==true then return true else return false end end --Locates a string saved within memory file function findInImageDataIndex(...) for _, str in ipairs({...}) do for i, v in ipairs(tableImageData) do if v.url == str or v.name == str then return i end end end return nil end --Round number (num) to the Nth decimal (dec) function round(num, dec) local mult = 10^(dec or 0) return math.floor(num * mult + 0.5) / mult end --Locates a button with a helper function function findButton(obj, func) if func==nil then error("No func supplied to findButton") end for _, v in ipairs(obj.getButtons()) do if func(v) then return v end end return nil end --Creation of buttons/inputs function createOpenCloseButton() local tooltip = "Open Table Control Panel" if controlActive then tooltip = "Close Table Control Panel" end self.createButton({ click_function="click_toggleControl", function_owner=self, position={0,0,0}, rotation={-45,0,0}, height=400, width=400, color={1,1,1,0}, tooltip=tooltip }) end function createSurfaceInput() local currentURL = obj_surface.getCustomObject().diffuse local nickname = "" if findInImageDataIndex(currentURL) ~= nil then nickname = tableImageData[findInImageDataIndex(currentURL)].name end self.createInput({ label="Nickname", input_function="none", function_owner=self, alignment=3, position={0,0,2}, height=224, width=4000, font_size=200, tooltip="Enter nickname for table image (only used for save)", value=nickname }) self.createInput({ label="URL", input_function="none", function_owner=self, alignment=3, position={0,0,3}, height=224, width=4000, font_size=200, tooltip="Enter URL for tabletop image", value=currentURL }) end function createSurfaceButtons() --Label self.createButton({ label="Tabletop Surface Image", click_function="none", position={0,0,1}, height=0, width=0, font_size=300, font_color={1,1,1} }) --Functional self.createButton({ label="Apply Image\nTo Table", click_function="click_applySurface", function_owner=self, tooltip="Apply URL as table image", position={2,0,4}, height=440, width=1400, font_size=200, }) self.createButton({ label="Save Image\nTo Memory", click_function="click_saveSurface", function_owner=self, tooltip="Record URL into memory (requires nickname)", position={-2,0,4}, height=440, width=1400, font_size=200, }) --Label self.createButton({ label="Load From Memory", click_function="none", position={0,0,5.5}, height=0, width=0, font_size=300, font_color={1,1,1} }) --Saves, created dynamically from memory file for i, memoryEntry in ipairs(tableImageData) do --Load local funcName = i.."loadMemory" local func = function(x,y) click_loadMemory(x,y,i) end self.setVar(funcName, func) self.createButton({ label=memoryEntry.name, click_function=funcName, function_owner=self, tooltip=memoryEntry.url, font_size=200, position={-0.6,0,6.5+0.5*(i-1)}, height=240, width=3300, }) --Delete local funcName = i.."deleteMemory" local func = function(x,y) click_deleteMemory(x,y,i) end self.setVar(funcName, func) self.createButton({ label="DELETE", click_function=funcName, function_owner=self, tooltip="", position={3.6,0,6.5+0.5*(i-1)}, height=240, width=600, font_size=160, font_color={1,0,0}, color={0.8,0.8,0.8} }) end end function createScaleInput() self.createInput({ label=string.char(8644), input_function="none", function_owner=self, alignment=3, position={-8.5,0,2}, height=224, width=400, font_size=200, tooltip="Table Width", value=round(obj_side_top.getScale().x, 1) }) self.createInput({ label=string.char(8645), input_function="none", function_owner=self, alignment=3, position={-7.5,0,2}, height=224, width=400, font_size=200, tooltip="Table Depth", value=round(obj_side_lef.getScale().x, 1) }) end function createScaleButtons() --Labels self.createButton({ label="Table Scale", click_function="none", position={-8,0,1}, height=0, width=0, font_size=300, font_color={1,1,1} }) self.createButton({ label=string.char(8644).." "..string.char(8645), click_function="none", position={-8,0,2}, height=0, width=0, font_size=300, font_color={1,1,1} }) self.createButton({ label="Move Hands:", click_function="none", position={-8.3,0,3}, height=0, width=0, font_size=200, font_color={1,1,1} }) --Disabled due to me removing the feature for technical reasons --[[ self.createButton({ label="Scale Hands:", click_function="none", position={-8.3,0,4}, height=0, width=0, font_size=200, font_color={1,1,1} }) ]] --Checkboxes local label = "" if checkData.move == true then label = string.char(10008) end self.createButton({ label=label, click_function="click_checkMove", function_owner=self, tooltip="Check to move hands when table is rescaled", position={-6.8,0,3}, height=224, width=224, font_size=200, }) --[[ local label = "" if checkData.scale == true then label = string.char(10008) end self.createButton({ label=label, click_function="click_checkScale", function_owner=self, tooltip="Check to scale the width of hands when table is rescaled", position={-6.8,0,4}, height=224, width=224, font_size=200, }) ]] --Apply button self.createButton({ label="Apply Scale", click_function="click_applyScale", function_owner=self, tooltip="Apply width/depth to table", position={-8,0,4}, height=440, width=1400, font_size=200, }) end --Data tables ref_noninteractable = { "afc863","c8edca","393bf7","12c65e","f938a2","9f95fd","35b95f", "5af8f2","4ee1f2","bd69bd" } ref_playerColor = { "White", "Brown", "Red", "Orange", "Yellow", "Green", "Teal", "Blue", "Purple", "Pink", "Black" } --Dummy function, absorbs unwanted triggers function none() endLuaScriptStateÇ{"cd":{"move":false,"scale":false},"tid":[{"name":"Felt - Green","url":"https://steamusercontent-a.akamaihd.net/ugc/1020573844624825793/FF91D48AB5415E01B8E9EFF7E2421C05AE05ACD2/"},{"name":"Felt - Gray","url":"https://steamusercontent-a.akamaihd.net/ugc/1836902512978660357/7A32A39FD692F3CEE69729A5B7E2C6AF1D00970E/"},{"name":"Felt - Red","url":"https://steamusercontent-a.akamaihd.net/ugc/5107676531851159442/76366CE0E933214A24710553DB94CEEDB3A4F629/"}]}XmlUI52GUIDf938a2NameCustom_AssetbundleTransform‰posXposY#ÀposZ ™™5ÀrotX Ü¥<½rotYrotZscaleX@scaleYð?scaleZð?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomAssetbundleÚAssetbundleURLihttps://steamusercontent-a.akamaihd.net/ugc/879750610978796471/14ED0DBD593370733A0309B0950004F33EB9FACA/AssetbundleSecondaryURLMaterialIndexTypeIndexLoopingEffectIndexLuaScriptLuaScriptStateXmlUI62GUID9f95fdNameCustom_AssetbundleTransform‰posXKÀposY#ÀposZrotX€rotY€V@rotZscaleX ™™@scaleYð?scaleZð?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomAssetbundleÚAssetbundleURLihttps://steamusercontent-a.akamaihd.net/ugc/879750610978796471/14ED0DBD593370733A0309B0950004F33EB9FACA/AssetbundleSecondaryURLMaterialIndexTypeIndexLoopingEffectIndexLuaScriptLuaScriptStateXmlUI72GUID35b95fNameCustom_AssetbundleTransform‰posXposY#ÀposZ ™™5@rotX Ü¥<½rotY€f@rotZscaleX@scaleYð?scaleZð?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomAssetbundleÚAssetbundleURLihttps://steamusercontent-a.akamaihd.net/ugc/879750610978796471/14ED0DBD593370733A0309B0950004F33EB9FACA/AssetbundleSecondaryURLMaterialIndexTypeIndexLoopingEffectIndexLuaScriptLuaScriptStateXmlUI82GUID5af8f2NameCustom_AssetbundleTransform‰posXK@posY#ÀposZrotX€rotYàp@rotZscaleX ™™@scaleYð?scaleZð?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomAssetbundleÚAssetbundleURLihttps://steamusercontent-a.akamaihd.net/ugc/879750610978796471/14ED0DBD593370733A0309B0950004F33EB9FACA/AssetbundleSecondaryURLMaterialIndexTypeIndexLoopingEffectIndexLuaScriptLuaScriptStateXmlUI9NGUIDe81db6NameScriptingTriggerTransform‰posX€Ùê6ÀposYàQ¸ú?posZrotX€rotYrotZscaleX@Ƙå?scaleYÀ Úò?scaleZ#@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI10NGUIDc5bb7cNameScriptingTriggerTransform‰posXÀâ;6ÀposYàQ¸ú?posZrotX€rotYrotZscaleX@Ƙå?scaleYÀ Úò?scaleZ#@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI11NGUID43ae52NameScriptingTriggerTransform‰posX€®Ž5ÀposYàQ¸ú?posZrotX€rotYrotZscaleX@Ƙå?scaleYÀ Úò?scaleZ#@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI12NGUID3c5749NameScriptingTriggerTransform‰posX€ ã4ÀposYàQ¸ú?posZrotX€rotYrotZscaleX@Ƙå?scaleYÀ Úò?scaleZ#@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI13NGUID07b4a6NameScriptingTriggerTransform‰posXÀÐ94ÀposYàQ¸ú?posZrotX€rotYrotZscaleX@Ƙå?scaleYÀ Úò?scaleZ#@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI142GUID4ee1f2Name Custom_ModelTransform‰posXposY#ÀposZrotXrotYC _¿rotZscaleX@scaleYð?scaleZ ™™@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/879750610978796176/4A5A65543B98BCFBF57E910D06EC984208223D38/DiffuseURLjhttps://steamusercontent-a.akamaihd.net/ugc/2059887766553038876/B11CE198C7F4820FEE547D4665CA8364A2029385/NormalURLColliderURLConvexMaterialIndexTypeIndexCustomShader‰SpecularColor&rð?gð?bð?SpecularIntensitySpecularSharpness@FresnelStrengthCastShadowsLuaScriptLuaScriptStateXmlUI15IGUIDe2cf9bName BlockSquareTransform‰posX@ ÷BÀposYàç¬ð?posZ€ãè+ÀrotXÀvO£>rotY è~f@rotZ`ìx¾scaleXÀ¶mó?scaleY@ñ¿?scaleZÀ¶mó?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rÀ½½í?gbaLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI16IGUIDd06145Name BlockSquareTransform‰posX@ ÷BÀposYàç¬ð?posZÀÌL2ÀrotX€þÂÙ¾rotY€é~f@rotZ tõž>scaleXÀ¶mó?scaleY@ñ¿?scaleZÀ¶mó?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rÀ½½í?gbaLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI17NGUIDd84035NameScriptingTriggerTransform‰posXFÀposY×£ @posZ"@rotX€rotYrotZscaleX`ff@scaleY`ff@scaleZà@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI18NGUID29a37cNameScriptingTriggerTransform‰posXCÀposY×£ @posZ"@rotX€rotYrotZscaleX`ff@scaleY`ff@scaleZà@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI19NGUIDce9f59NameScriptingTriggerTransform‰posX@ÀposY×£ @posZ"@rotX€rotYrotZscaleX`ff@scaleY`ff@scaleZà@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI20NGUID98984bNameScriptingTriggerTransform‰posXFÀposY×£ @posZ@rotX€rotYrotZscaleX`ff@scaleY`ff@scaleZà@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI21NGUIDd2bb17NameScriptingTriggerTransform‰posXCÀposY×£ @posZ@rotX€rotYrotZscaleX`ff@scaleY`ff@scaleZà@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI22NGUIDa19d78NameScriptingTriggerTransform‰posX@ÀposY×£ @posZ@rotX€rotYrotZscaleX`ff@scaleY`ff@scaleZà@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI23NGUID109f5cNameScriptingTriggerTransform‰posXFÀposY×£ @posZÀrotX€rotYrotZscaleX`ff@scaleY`ff@scaleZà@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI24NGUID5dc8aaNameScriptingTriggerTransform‰posXCÀposY×£ @posZÀrotX€rotYrotZscaleX`ff@scaleY`ff@scaleZà@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI25NGUID08a5e8NameScriptingTriggerTransform‰posX@ÀposY×£ @posZÀrotX€rotYrotZscaleX`ff@scaleY`ff@scaleZà@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI26NGUID6bad00NameScriptingTriggerTransform‰posXFÀposY×£ @posZ"ÀrotX€rotYrotZscaleX`ff@scaleY`ff@scaleZà@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI27NGUIDa2aee6NameScriptingTriggerTransform‰posXCÀposY×£ @posZ"ÀrotX€rotYrotZscaleX`ff@scaleY`ff@scaleZà@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI28NGUID71d038NameScriptingTriggerTransform‰posX@ÀposY×£ @posZ"ÀrotX€rotYrotZscaleX`ff@scaleY`ff@scaleZà@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?a`PPà?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsLuaScriptLuaScriptStateXmlUI29–GUIDfa3559NameFogOfWarTriggerTransform‰posX ;(CÀposY7¢ü¿posZ_£è?rotX€rotYrotZscaleX`kó1@scaleY`ff@scaleZÀ@c8@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rÀÿÿÏ?gÀÿÿÏ?bÀÿÿÏ?aè?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsFogColorBlackFogHidePointersFogReverseHidingFogSeethroughLuaScriptLuaScriptStateXmlUI30ÌGUID674887Name Custom_BoardTransform‰posX€\£s¾posY€¤ãñ?posZ@É9˜¾rotX`Kæ¾rotY€ÿf@rotZÀø™²>scaleXàþÿ @scaleYàþÿ @scaleZàþÿ @NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r --é?g --é?b --é?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomImage¾ImageURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238774745/141CA79CC14C3F25E6EAE74E11D33F6EA065140F/ImageSecondaryURLImageScalarð?WidthScale€¼�ð?LuaScriptLuaScriptStateXmlUIAttachedSnapPoints®0}Position&x |AÀy€§óâ?zà÷»@Rotation&x äªë>y —v@z‹…¥¾Tags0Share1}Position&x@²QÀy §óâ?zÀÖ6@Rotation&xàŒ0é>yà¨v@zÀ¬Šµ>Tags0Money25Position&xÀÁ³@y¦óâ?z È`@35Position&x ?W@yà¥óâ?z€_b@45Position&xv@y@§óâ?z ½n@55Position&xÀ¶Ÿ @yà¦óâ?zÀMi@65Position&x€ó2@y@§óâ?zDg@75Position&x Šµ@y§óâ?z€Wb@85Position&xÀ»c@y§óâ?z Fg@95Position&xÀMú?y§óâ?zài@105Position&x ">ó?y§óâ?zÀªa@115Position&xÀ·‹é?y §óâ?z`}e@125Position&xÀ«Ö×?y §óâ?z ¡c@135Position&x@‹U¨¿y §óâ?z€A`@145Position&x 8äÞ¿yà¥óâ?z€Ã]@155Position&x *ôì¿y §óâ?z .a@165Position&xT(õ¿y §óâ?zàIb@175Position&x Äåû¿y §óâ?zÀša@185Position&x@•[Ày §óâ?z ø`@195Position&xàh¡Ày §óâ?z 4c@205Position&x`GþÀy@§óâ?z ¹e@215Position&xàf Ày@§óâ?zb`@225Position&x >ÄÀyà¦óâ?zà5d@235Position&x øÀyà¦óâ?z`­`@245Position&x`4ÃÀy§óâ?zàíg@255Position&xÀm|Ày§óâ?zà‚d@265Position&xàz$Ày@§óâ?z€ëb@275Position&x òÈÀy§óâ?z@\b@285Position&x€”ƒÀy§óâ?z€oc@295Position&x ä*Ày §óâ?z@e@305Position&x@g×Ày §óâ?zÀ5b@315Position&xàÞŠÀy §óâ?z@?_@325Position&x ºœÀy@§óâ?z@P�@335Position&xਛÀy §óâ?z`¼Ú@345Position&x  Ày@§óâ?z ‹@355Position&xÀ©žÀy`§óâ?zÀÈa@365Position&x ÀšÀy@§óâ?z ª“@375Position&xàžÀy€§óâ?z€ÔÚ@385Position&xÀ3¢Ày€§óâ?z Þ]@395Position&xà�šÀy §óâ?zÀ¡@405Position&x@¡Ày §óâ?zÀÒH @415Position&xàN¨Àyà§óâ?z@JÑ @425Position&xà©ÀyÀ§óâ?z1J@435Position&x€’¥Àyà§óâ?z€pÍ@445Position&xà&¦Ày ¨óâ?zÀ�uþ?455Position&x@ͦÀyà§óâ?zóÈ÷?465Position&x€ªÀy §óâ?z€I¡ð?475Position&x€ë¦Ày@¨óâ?zÎŒã?485Position&xàê¡Ày ¨óâ?zà"?Å?495Position&xà5¦Ày@¨óâ?z`àÊп505Position&xÀ¢Ày€¨óâ?z6æ¿515Position&x|œÀy@¨óâ?z€Zdò¿52}Position&x@À ö?y@§óâ?z`m¦@Rotation&x`T{æ>y€¢ým?zà�ç¼>Tags0House53}Position&x`nšØ?y@§óâ?z`§¥@Rotation&x€v¾ç>y üàm?z@ŽŸ>Tags0House54}Position&x`4ã¿y@§óâ?zà1­@Rotation&x€Ï‹ß>y üàm?z  MÂ>Tags0House55}Position&xkVØ?y@§óâ?zÐ @Rotation&x@·ŠÄ¾y üàm?zàxy>Tags0House56}Position&xàO²ë?y@§óâ?z` @Rotation&x ¿æÚ>y üàm?z@ÃÛ§>Tags0House57}Position&xïõ?y §óâ?z`1 @Rotation&x€"Wå>y üàm?z­Ç±¾Tags0House58}Position&x Ó×ý?y §óâ?zÀuý@Rotation&xÀnžà>y î6n?z€¦Vž>Tags0House59}Position&x ßÍ@y`§óâ?z b4@Rotation&xà³—å>y üàm?zP.~>Tags0House60}Position&x ®Ó@y€§óâ?z §>@Rotation&x v{â>y üàm?z€Iæ×>Tags0House61}Position&x #©ý?y€§óâ?z`?@Rotation&xàouò>y üàm?zÀÁ¦à>Tags0House62}Position&x`æÂõ?y€§óâ?z@o@@Rotation&x€ü�Ø>y€¢ým?z`rŒç>Tags0House63}Position&x€fÌë?y€§óâ?z€\A@Rotation&x€�Û>yÀVÄm?zÀ'Šâ>Tags0House64}Position&x@ÆjØ?y@§óâ?zàE@Rotation&xà4ï>yÀVÄm?z Áú‘>Tags0House65}Position&x`«á»¿y@§óâ?zàC@Rotation&x«Eß>y üàm?z@ŸÙ>Tags0House66}Position&x Dã¿y@§óâ?z@ˆ=@Rotation&xÀ"â>yÀVÄm?z@­nà>Tags0House31~GUID902839Name Custom_TileTransform‰posX SI@posYàWfï?posZà¾x6@rotX YH?rotY€í~f@rotZ`¼y`¿scaleXÀ�ô@scaleYð?scaleZÀ�ô@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?Tags0BoardLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomImageImageURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238777041/1E030D00E69722643E35E1D631C7DD4D8F75BCFE/ImageSecondaryURLImageScalarð?WidthScaleCustomTile8TypeThickness ™™É?StackableStretchLuaScriptLuaScriptStateXmlUIAttachedSnapPoints0}Position&xD­á?yÀ›™É?z€piÔ?Rotation&x`ÑÑ>y £v@z€a‰Ù¾Tags0Share1}Position&x@æaé¿y œ™É?z`Lãä?Rotation&x`ñmj¾y`àv@zàÔÿH¾Tags0Money2}Position&x@p|é¿y œ™É?z‚Ž?Rotation&x€?^*¾y€àv@z@¸2`>Tags0Money3}Position&x •�é¿y œ™É?z@3ä¿Rotation&xÀS‰E¾y ü‹?z€f@Tags0Money32ÆGUID7f7dc1Name Custom_TileTransform‰posX 9(6@posYàÉW@posZ ²ÀrotX lÜz¾rotY€f@rotZ »èz>scaleXð?scaleYð?scaleZð?NicknameDescription+50 Point MarkerGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomImagekImageURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238780161/9C63452379D2177EE224A60FD5F8A5720CEBC463/ImageSecondaryURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238780242/A29F4429B7A7DB6DB47654D5864B0BC5D29AE846/ImageScalarð?WidthScaleCustomTile8TypeThickness ™™É?StackableStretchLuaScriptLuaScriptStateXmlUI33ÆGUID1b6a60Name Custom_TileTransform‰posX@“h7@posYÊW@posZàQ„ÀrotX M{¾rotY€f@rotZ Q �¾scaleXð?scaleYð?scaleZð?NicknameDescription+50 Point MarkerGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomImagekImageURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238780557/53DFBEC2640DE837F3B4657CF1742299A2B49A77/ImageSecondaryURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238780836/B8AB52576CB8BBD5F2E5B2B6A3664C0E949B716D/ImageScalarð?WidthScaleCustomTile8TypeThickness ™™É?StackableStretchLuaScriptLuaScriptStateXmlUI34ÆGUID980900Name Custom_TileTransform‰posX Hs6@posY@ÊW@posZ >="ÀrotX …׿¾rotY€f@rotZ@­O£¾scaleXð?scaleYð?scaleZð?NicknameDescription+50 Point MarkerGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomImagekImageURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238781406/CFD902B709210D236120A521D2ACDD84A2F297DC/ImageSecondaryURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238781511/012FF93AE4A621F7F5A91998BDB7263944CA3E46/ImageScalarð?WidthScaleCustomTile8TypeThickness ™™É?StackableStretchLuaScriptLuaScriptStateXmlUI35~GUID98b24aName Custom_TileTransform‰posX óI@posY "fï?posZ€ÊÚ@rotX`Ó¶J?rotY �f@rotZ@î=b¿scaleXÀ�ô@scaleYð?scaleZÀ�ô@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?Tags0BoardLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomImageImageURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238821690/843E4A601680BC0D4367A8A35C3B251FCF5974CD/ImageSecondaryURLImageScalarð?WidthScaleCustomTile8TypeThickness ™™É?StackableStretchLuaScriptLuaScriptStateXmlUIAttachedSnapPoints0}Position&x`Îwâ?yÀ›™É?zà/pÔ?Rotation&xà†|Ñ>y }v@zhXÚ¾Tags0Share1}Position&x ŸIè¿y œ™É?z@8Îä?Rotation&x€ÁÛc>yÀ¬v@z 9%R>Tags0Money2}Position&x@cè¿y œ™É?z 껈?Rotation&x€ö,¾yà¬v@z —L¾Tags0Money3}Position&x@ýrè¿y œ™É?z`5Hä¿Rotation&x@"Q>y@VQ?z€f@Tags0Money36~GUID5dfd5dName Custom_TileTransform‰posX@±I@posY@ýeï?posZ  ƒ6ÀrotX ƒL?rotYÒ|f@rotZàYc¿scaleXÀ�ô@scaleYð?scaleZÀ�ô@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?Tags0BoardLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomImageImageURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238824928/20A473482A4737895BAD988965A15C17771CE0D7/ImageSecondaryURLImageScalarð?WidthScaleCustomTile8TypeThickness ™™É?StackableStretchLuaScriptLuaScriptStateXmlUIAttachedSnapPoints0}Position&x`¹Mâ?y@�™É?z€#AÔ?Rotation&x@v%Ñ>y€’v@zàlæÙ¾Tags0Share1}Position&x ¬¾è¿yÀœ™É?z ¸öä?Rotation&x@Ÿi>yÀEv@zàâžN>Tags0Money2}Position&x€ÄÕè¿yÀœ™É?z€¥m‘?Rotation&x@±È,>yàEv@z ñøX¾Tags0Money3}Position&xÀmãè¿yÀœ™É?zà¹ä¿Rotation&xÀß¼g>y`�v@z€f@Tags0Money37~GUIDed8925Name Custom_TileTransform‰posX I@posY@Ÿeï?posZ ¹ ÀrotXÀ>P?rotY`ƒ€f@rotZ`ç,f¿scaleXÀ�ô@scaleYð?scaleZÀ�ô@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?Tags0BoardLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomImageImageURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238828343/6E17EA6810DDD6A91AD0865F92125702B8B87F33/ImageSecondaryURLImageScalarð?WidthScaleCustomTile8TypeThickness ™™É?StackableStretchLuaScriptLuaScriptStateXmlUIAttachedSnapPoints0}Position&x`~á?yÀ›™É?z uFÔ?Rotation&x€y§Ð>y€×v@zà°?Ù¾Tags0Share1}Position&xÀ†]é¿y@œ™É?z ±åä?Rotation&xÀ³Ñ6>yÀ¤v@zàjYd¾Tags0Money2}Position&x€¼vé¿y@œ™É?z`XšŽ?Rotation&x€ËHn>yà¤v@zŠÿG¾Tags0Money3}Position&x`‰†é¿y œ™É?z ¹0ä¿Rotation&x %b¾yhüM¿z€f@Tags0Money38!GUID6cb52eName Custom_ModelTransform‰posXÿF@posY •Œù?posZ@€(@rotX ¿J¿rotY`èv@rotZ ÇCb?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI39!GUID5983b2Name Custom_ModelTransform‰posX€ @posY€E« @posZ€(ÀrotXÀ¸ë>rotYàEŒ?rotZÀ7ô´>scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&róÿÏ?góÿÏ?bóÿÏ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI40!GUID348b8fName Custom_ModelTransform‰posXà!§8@posY€C« @posZ¥¨+@rotXÀ0äå>rotY`yHs¿rotZÀ?J޾scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI41!GUID520849Name Custom_ModelTransform‰posXàQ 3@posYE« @posZ@ ÀrotX  å>rotY ¥¤>rotZ Fº–>scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI42JGUIDfd7eccName Custom_ModelTransform‰posX(ÀposY °V@posZ!ÀrotXP4À¾rotY €f@rotZÀb¦>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI438GUID4a4d11Name Custom_ModelTransform‰posXÀW‘ ÀposY`yß @posZ æ¯8ÀrotXÀ•¯>rotY ^€f@rotZ€f@scaleX@ffâ?scaleY@ffâ?scaleZ@ffâ?NicknameB&ODescriptionGMNotesAltLookAngle&xyzColorDiffuse&r '¿?gªˆØ?b€‡˜ë?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshêMeshURL'http://pastebin.com/raw.php?i=Kp1EgH5cDiffuseURL https://i.imgur.com/bEPzdCi.jpgNormalURLColliderURL'http://pastebin.com/raw.php?i=Kp1EgH5cConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI448GUID173655Name Custom_ModelTransform‰posX [€#ÀposY€yß @posZ ç³8ÀrotXÀê@Õ¾rotY ’~f@rotZ€f@scaleX@ffâ?scaleY@ffâ?scaleZ@ffâ?NicknameC&ODescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?bÀ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshêMeshURL'http://pastebin.com/raw.php?i=Kp1EgH5cDiffuseURL https://i.imgur.com/bEPzdCi.jpgNormalURLColliderURL'http://pastebin.com/raw.php?i=Kp1EgH5cConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI458GUIDa32a5aName Custom_ModelTransform‰posX­àÀposY@yß @posZ`8µ8ÀrotXàsºÛ¾rotY`©|f@rotZ€f@scaleX@ffâ?scaleY@ffâ?scaleZ@ffâ?NicknameNYCDescriptionGMNotesAltLookAngle&xyzColorDiffuse&ri“È?g€—næ?b@ú€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshêMeshURL'http://pastebin.com/raw.php?i=Kp1EgH5cDiffuseURL https://i.imgur.com/bEPzdCi.jpgNormalURLColliderURL'http://pastebin.com/raw.php?i=Kp1EgH5cConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI46;GUID9916d5Name Custom_ModelTransform‰posX`á2ÀposY€yß @posZ@x¤8ÀrotX õ ´>rotYø~f@rotZ€f@scaleX@ffâ?scaleY@ffâ?scaleZ@ffâ?NicknameWabashDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€óÿÏ?g€óÿÏ?b€óÿÏ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshêMeshURL'http://pastebin.com/raw.php?i=Kp1EgH5cDiffuseURL https://i.imgur.com/bEPzdCi.jpgNormalURLColliderURL'http://pastebin.com/raw.php?i=Kp1EgH5cConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI478GUIDb3cbcfName Custom_ModelTransform‰posXÀö�ÀposY€yß @posZ`è³8ÀrotXà?CÖ>rotY ‹f@rotZ€f@scaleX@ffâ?scaleY@ffâ?scaleZ@ffâ?NicknamePRRDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g �™¹?b J¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshêMeshURL'http://pastebin.com/raw.php?i=Kp1EgH5cDiffuseURL https://i.imgur.com/bEPzdCi.jpgNormalURLColliderURL'http://pastebin.com/raw.php?i=Kp1EgH5cConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI48ÆGUIDbc1e88Name Custom_TileTransform‰posXà¦m7@posYÀÉW@posZ@�§ÀrotX`–/q¾rotY€f@rotZ Ð¬>scaleXð?scaleYð?scaleZð?NicknameDescription+50 Point MarkerGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomImagekImageURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238808552/0FE226D2E10AC009D9904250A9D05AA84AE38DC4/ImageSecondaryURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238799730/8F7A64E183AA018C9C479CBECB6D9F27FE606F76/ImageScalarð?WidthScaleCustomTile8TypeThickness ™™É?StackableStretchLuaScriptLuaScriptStateXmlUI49ÆGUID22ac9cName Custom_TileTransform‰posX€æÓ2@posY@ÊW@posZêû"ÀrotX@•aÔ¾rotY€f@rotZ@:…q¾scaleXð?scaleYð?scaleZð?NicknameDescription+50 Point MarkerGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomImagekImageURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238779172/A099658D44636C0518C8F1823D042DFC09812DA0/ImageSecondaryURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238779774/05CCDCBC309A985486EE8F31118FE64ADE39C44B/ImageScalarð?WidthScaleCustomTile8TypeThickness ™™É?StackableStretchLuaScriptLuaScriptStateXmlUI50!GUID987d9aName Custom_ModelTransform‰posX`ç5@posY D« @posZ °@rotX`‹¢à>rotY€Ív@rotZ Qñ¢¾scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI51!GUID16dff8Name Custom_ModelTransform‰posX€ÿßF@posYÀÒŒù?posZà€(@rotX 3ÎJ¿rotY€HÑž?rotZÀAb?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI52!GUIDaada55Name Custom_ModelTransform‰posXàÿŸG@posYà�ù?posZà€(@rotXh»J¿rotYÀ¦v@rotZOAb?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI53!GUID61ba9eName Custom_ModelTransform‰posXàÿŸG@posYãŒù?posZ@€"@rotX@ ÍJ¿rotYà¿·�?rotZ Ab?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI54!GUIDc01eeeName Custom_ModelTransform‰posX@ÿ_H@posYàL�ù?posZ €(@rotXà­ÐJ¿rotY@±s¤?rotZ ÕAb?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI55!GUID7295caName Custom_ModelTransform‰posX@H@posY@!�ù?posZ€$@rotXàœÏJ¿rotY`–=›?rotZ`é@b?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI56!GUID41d871Name Custom_ModelTransform‰posX@ÿÿE@posY`€Œù?posZ '@rotX`z¼J¿rotY`Žv@rotZ›Bb?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI57!GUIDeb4380Name Custom_ModelTransform‰posXÀF@posY@½Œù?posZ@'@rotX`OäI¿rotY€Ñ�?rotZ€28b?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI58!GUID298bc1Name Custom_ModelTransform‰posX ÿG@posY`úŒù?posZ '@rotXÀªÔJ¿rotYÀÁ£?rotZÀ=Bb?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI59!GUID33b4fbName Custom_ModelTransform‰posX@ÿŸG@posY€ùŒù?posZ€%@rotX`»ÑJ¿rotY`ﯦ?rotZÀ—@b?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI60!GUID429a58Name Custom_ModelTransform‰posX`ÿ?H@posY 7�ù?posZ'@rotX€•ØI¿rotYÀé&œ?rotZ 6b?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI61!GUIDfd304dName Custom_ModelTransform‰posX `H@posY 6�ù?posZ`€%@rotX ¦àJ¿rotY@ø—?rotZ =Bb?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI62!GUID4412c1Name Custom_ModelTransform‰posX F@posY Œù?posZ€€%@rotX@QâJ¿rotYÀ9˜?rotZ€?b?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI63!GUIDa5ae36Name Custom_ModelTransform‰posXàU-3@posY`D« @posZ•öñ?rotX`;äô>rotY@‡q?rotZÀö¼¾scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI64!GUID4f9d72Name Custom_ModelTransform‰posX ÿßF@posY@¼Œù?posZ`€%@rotX`yÎJ¿rotY Â;›?rotZhAb?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI65!GUID833c52Name Custom_ModelTransform‰posX ÿ¿F@posY§Œù?posZÀ$@rotX€ªÈJ¿rotYÀNØ?rotZ@A@b?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI66!GUIDc4c846Name Custom_ModelTransform‰posXàF@posY¦Œù?posZ@€"@rotXÀ ÎJ¿rotYÀöÞ™?rotZ Ab?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI67!GUID997e99Name Custom_ModelTransform‰posX`H@posY@ �ù?posZ€€"@rotX yÌJ¿rotY€Îv@rotZÀCb?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI68!GUID58f9ecName Custom_ModelTransform‰posX`ÿG@posY äŒù?posZ€$@rotX *ÇJ¿rotYÀä+¡?rotZÕ>b?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI69!GUID630f41Name Custom_ModelTransform‰posX@ÿF@posYàhŒù?posZà€"@rotX SáJ¿rotY`�ž?rotZ€Bb?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI70!GUID7c23e0Name Custom_ModelTransform‰posXÀÿÿE@posYÀiŒù?posZÀ$@rotXàcÂJ¿rotYÀZƒ?rotZ`¨?b?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI71!GUID9185a5Name Custom_ModelTransform‰posX€%@posY€E« @posZ€*ÀrotX€$Ø>rotY`Ù�?rotZÀ ‹´>scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&róÿÏ?góÿÏ?bóÿÏ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI72!GUID75bc8bName Custom_ModelTransform‰posXF€)@posY`E« @posZ ½ˆ*ÀrotXì€Ô>rotY`´v@rotZ% ˆ¾scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&róÿÏ?góÿÏ?bóÿÏ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI73!GUIDa56a7dName Custom_ModelTransform‰posX€(@posY`E« @posZ€(ÀrotXàiTé>rotY€.í™?rotZ ¹ã½>scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&róÿÏ?góÿÏ?bóÿÏ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI74!GUID757d36Name Custom_ModelTransform‰posX€$@posY€E« @posZ€(ÀrotX ñ±ë>rotYíŠ?rotZ@ª™½¾scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&róÿÏ?góÿÏ?bóÿÏ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI75!GUID0f275dName Custom_ModelTransform‰posX ²z(@posY€E« @posZ V€,ÀrotXÚò>rotY`¿x@?rotZ Ý^žscaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&róÿÏ?góÿÏ?bóÿÏ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI76!GUID4efa7aName Custom_ModelTransform‰posX€$@posY€E« @posZ€,ÀrotXÀZÇØ>rotY@ª€?rotZ Æº¿¾scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&róÿÏ?góÿÏ?bóÿÏ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI77!GUID9cc854Name Custom_ModelTransform‰posX€!@posY E« @posZ€*ÀrotXÀýkÕ>rotY€é‚?rotZÀ—ñ°¾scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&róÿÏ?góÿÏ?bóÿÏ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI78!GUID7b0d97Name Custom_ModelTransform‰posX€ @posY€E« @posZ€,ÀrotX€tè×>rotYàý�?rotZཾscaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&róÿÏ?góÿÏ?bóÿÏ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI79!GUID1baa2eName Custom_ModelTransform‰posX#@posYÀE« @posZ.ÀrotX`üÈÇ>rotY`‚?rotZ 6ö¾scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&róÿÏ?góÿÏ?bóÿÏ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI80!GUIDd76b13Name Custom_ModelTransform‰posX'@posY E« @posZ.ÀrotXàß×>rotY`‡?rotZ¾¹¾scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&róÿÏ?góÿÏ?bóÿÏ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI81!GUID1cbc82Name Custom_ModelTransform‰posXþF@posY`yŒù?posZ`ø¿1ÀrotX`ìÄL¿rotYËv@rotZ@…Yc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI82!GUID8198c8Name Custom_ModelTransform‰posX@àF@posY ºŒù?posZ À1ÀrotXü¤L¿rotY Pv@rotZ@%Wc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI83!GUIDabbec0Name Custom_ModelTransform‰posXÀýŸG@posY@ûŒù?posZ`ø¿1ÀrotXà;£L¿rotY �v@rotZ@¿Zc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI84!GUID0098f4Name Custom_ModelTransform‰posXÀ@F@posY`xŒù?posZ€2ÀrotX`-§L¿rotY`Ov@rotZ [c?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI85!GUID61ce94Name Custom_ModelTransform‰posX ÿÿF@posY ¹Œù?posZ€€2ÀrotX@\ÃL¿rotY v@rotZ ŒZc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI86!GUID46c6b4Name Custom_ModelTransform‰posX@ÀG@posY ùŒù?posZ€2ÀrotX ÊÁL¿rotY`Üv@rotZ`Yc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI87!GUID469947Name Custom_ModelTransform‰posX`ÿ_H@posY<�ù?posZý¿1ÀrotXÀà´L¿rotY—v@rotZ½Vc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI88!GUIDc92e7fName Custom_ModelTransform‰posXþ_H@posYà �ù?posZ ø¿4ÀrotXÀ£¶L¿rotYäv@rotZ@#Wc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI89!GUID750289Name Custom_ModelTransform‰posX G@posYãŒù?posZ þ?3ÀrotX !ÃL¿rotYàµv@rotZ +Zc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI90!GUIDabf29eName Custom_ModelTransform‰posX€H@posY€:�ù?posZ@€2ÀrotX€Z®L¿rotY`Ìv@rotZ _Vc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI91!GUID0fd339Name Custom_ModelTransform‰posXÀ`H@posY #�ù?posZÀ@3ÀrotX 6ÃL¿rotYY±¡?rotZÀfYc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI92!GUIDcd0b88Name Custom_ModelTransform‰posXÀÿF@posY€aŒù?posZÀý?3ÀrotXÀ#½L¿rotY kv@rotZ@¬Zc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI93!GUIDe374e8Name Custom_ModelTransform‰posX þßF@posY@¢Œù?posZÀü?3ÀrotXÀŸÈL¿rotYÈv@rotZÀßYc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI94!GUID8fcde3Name Custom_ModelTransform‰posXàÿÿF@posY¡Œù?posZà4ÀrotXÀYÂL¿rotY€¬v@rotZÀcWc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI95!GUID1dcad8Name Custom_ModelTransform‰posX@ª¿G@posYàáŒù?posZ òþ3ÀrotXÀPUL¿rotY@§{v@rotZ€V_c?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI96!GUID1ee5bdName Custom_ModelTransform‰posXàÿ?F@posY@`Œù?posZ@4ÀrotX`‡«L¿rotYàdv@rotZ 7Xc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI97!GUIDabcbfdName Custom_ModelTransform‰posX þŸG@posYàÊŒù?posZ ø¿4ÀrotXÀ[M¿rotY€ó¹Ã?rotZ`XUc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI98!GUID0967c5Name Custom_ModelTransform‰posX`àF@posY@ŠŒù?posZÀ À4ÀrotXó9N¿rotY@ùñ?rotZ`x2c?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI99!GUID474536Name Custom_ModelTransform‰posXÀþH@posY "�ù?posZ@ùÿ3ÀrotX ¶ÇL¿rotY€¾v@rotZà3Yc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI100!GUID1f0608Name Custom_ModelTransform‰posX€ F@posY`IŒù?posZà À4ÀrotX€RÑL¿rotY  ç‘?rotZ€ Yc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI101!GUID9f24daName Custom_ModelTransform‰posX þE@posYÀŒù?posZ`ûÿ3ÀrotXàg²L¿rotY Ÿv@rotZ ![c?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI102!GUIDb5f90bName Custom_ModelTransform‰posX``E@posYÀ Œù?posZ@3ÀrotX@¸³L¿rotYÀÓv@rotZ`([c?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI103!GUIDbb905eName Custom_ModelTransform‰posX€€E@posY@7Œù?posZ €2ÀrotXপL¿rotYà²üi¿rotZ€pVc?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€h“È?g€—næ?bÀù€Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI104!GUID748a75Name Custom_ModelTransform‰posX`E@posYBŒù?posZ@€%@rotX ´ËJ¿rotYyà›?rotZÀ3Ab?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rà%5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI105!GUIDe8a476Name Custom_ModelTransform‰posX þßE@posY@®Œù?posZ`@;@rotXàNH¿rotY �š ?rotZy`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI106!GUID318781Name Custom_ModelTransform‰posX F@posY`åŒù?posZ`@;@rotX éQH¿rotY€\ã˜?rotZà†y`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI107!GUID40fb41Name Custom_ModelTransform‰posXàÿÿE@posY ­Œù?posZ@€:@rotXÀ”CH¿rotY@B#¿rotZVz`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI108!GUIDb7e4d4Name Custom_ModelTransform‰posX€ÿ¿F@posY€äŒù?posZ €:@rotX@•OH¿rotY€Ö`�?rotZÖz`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI109!GUID41bf5dName Custom_ModelTransform‰posXàþ_G@posY`�ù?posZÀ@;@rotX`sGH¿rotY@ìú¢?rotZàZy`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI110!GUID4d03fbName Custom_ModelTransform‰posX ÿG@posY �ù?posZà€:@rotXÓ>H¿rotY`ƒv@rotZ`{`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI111!GUID18d6bfName Custom_ModelTransform‰posXÿG@posYöŒù?posZàÀ9@rotX „HH¿rotYà�„•?rotZ ô|`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI112!GUID3224ccName Custom_ModelTransform‰posXàÿßE@posYà™Œù?posZÀÀ9@rotX`Ô1H¿rotY@ŸÇ’?rotZ€Íy`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI113!GUID101289Name Custom_ModelTransform‰posX€ÿH@posY S�ù?posZ`@;@rotXà"JH¿rotY ¼?rotZà¨y`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI114!GUID39ea18Name Custom_ModelTransform‰posX ÿ?H@posY R�ù?posZ@€:@rotXàÔ?H¿rotYÀÇv@rotZ ‡|`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI115!GUID452493Name Custom_ModelTransform‰posX` H@posY`?�ù?posZÀÀ9@rotX è@H¿rotYà¹v@rotZ x|`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI116!GUID9aa379Name Custom_ModelTransform‰posX @H@posY >�ù?posZÀÿÿ8@rotXÀdwH¿rotY £xÀ?rotZà–v`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI117!GUID759b5eName Custom_ModelTransform‰posX ÿ¿F@posY ÐŒù?posZÀ9@rotXàtKH¿rotYÀ-’R?rotZÀ|z`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI118!GUIDe7c6c8Name Custom_ModelTransform‰posXÀÿG@posY@�ù?posZÀ9@rotX@êPH¿rotYÎc‰?rotZày`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI119!GUIDcb65adName Custom_ModelTransform‰posX€ÿÿE@posY™Œù?posZ9@rotX š:H¿rotYàvv@rotZ §{`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI120!GUIDd7c656Name Custom_ModelTransform‰posX€ÿ_G@posYôŒù?posZ`@8@rotX *DH¿rotY ®v@rotZ@}`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI121!GUIDb6c016Name Custom_ModelTransform‰posX ÿŸF@posYÀ¼Œù?posZà@8@rotX ˜CH¿rotY@ßv@rotZ"z`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI122!GUID3cd30eName Custom_ModelTransform‰posX@ÿH@posY`+�ù?posZ @8@rotX€BH¿rotYà‹v@rotZ ,{`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI123!GUIDbf2fa9Name Custom_ModelTransform‰posX àE@posY€…Œù?posZà@8@rotXÀœMH¿rotY€Ìv@rotZ z`?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g €™¹?b I¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI124!GUID4570aaName Custom_ModelTransform‰posX€ÿ_F@posY@HŒù?posZàýÿÀrotX ½.P¿rotY@Ù}k?rotZ �0f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI125!GUID12cd88Name Custom_ModelTransform‰posX€ G@posYà’Œù?posZ`KÀrotX`pP¿rotYvv@rotZ /f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI126!GUIDf7b575Name Custom_ModelTransform‰posXà€F@posY`GŒù?posZo ÀrotXàÂ&P¿rotY�v@rotZ f0f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI127!GUID4833edName Custom_ModelTransform‰posXÀÿ?G@posY ‘Œù?posZÀ ÀrotX P¿rotY@‡v@rotZ@ä0f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI128!GUIDdf793fName Custom_ModelTransform‰posXÀE@posYý‹ù?posZ l ÀrotX@_0P¿rotYÀÒúž?rotZÀ?.f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI129!GUID641187Name Custom_ModelTransform‰posXàG@posYàÜŒù?posZ  ÀrotX� P¿rotY y5�?rotZ <1f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI130!GUID1bbef9Name Custom_ModelTransform‰posX H@posYÜŒù?posZ@3 ÀrotXà:0P¿rotY@鉙?rotZà�-f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI131!GUID937599Name Custom_ModelTransform‰posXààG@posY@ÂŒù?posZÀ ÀrotX ¿*P¿rotY ¯–?rotZ€P/f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI132!GUIDb3cbc2Name Custom_ModelTransform‰posXÿ_F@posY€-Œù?posZ€ùÿÀrotX h(P¿rotYÀ…v@rotZ 2f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI133!GUID6de7a5Name Custom_ModelTransform‰posXàÿG@posY wŒù?posZ€ ÀrotX€Á,P¿rotY€*Ûf¿rotZ@_.f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI134!GUIDd1d097Name Custom_ModelTransform‰posX@ E@posY ã‹ù?posZÀÀrotX v)P¿rotY`½v@rotZà².f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI135!GUIDcf3c4aName Custom_ModelTransform‰posX` H@posY`'�ù?posZ@RÀrotXõP¿rotY€p ?rotZàA,f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI136!GUIDfdc817Name Custom_ModelTransform‰posX€ÀH@posY@&�ù?posZ3 ÀrotXÀ)P¿rotYÀݘ?rotZ  0f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI137!GUIDbddffaName Custom_ModelTransform‰posXÀ H@posY` �ù?posZ 'ÀrotX °*P¿rotY`øô£?rotZ ´.f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI138!GUID87a112Name Custom_ModelTransform‰posXàÿ¿E@posYàá‹ù?posZ€ÀrotXÀš&P¿rotY hB’?rotZ€l,f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI139!GUIDcc573cName Custom_ModelTransform‰posXàÀH@posY` �ù?posZÀ/ÀrotX @.P¿rotY€h ˜?rotZ@~/f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI140!GUID94fcaaName Custom_ModelTransform‰posX@@G@posYÀvŒù?posZ -ÀrotX@/P¿rotYFœœ?rotZ`�-f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI141!GUID5b5ffdName Custom_ModelTransform‰posX H@posY ÁŒù?posZ€0ÀrotX€#$P¿rotY`ø2Ÿ?rotZ€¾.f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI142!GUIDc81e53Name Custom_ModelTransform‰posXà€F@posY`,Œù?posZ€1ÀrotX@o,P¿rotY «’ ?rotZ€|0f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI143!GUID6535c8Name Custom_ModelTransform‰posX àG@posY@§Œù?posZ +ÀrotXà'P¿rotYðc›?rotZ <.f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI144!GUID2c5a22Name Custom_ModelTransform‰posXÀ G@posYà\Œù?posZà1ÀrotXàö[P¿rotY`Šø•?rotZ€e0f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI145!GUID1d9f02Name Custom_ModelTransform‰posXà H@posY@ñŒù?posZ1ÀrotX`S2P¿rotYàdÌ¡?rotZ`}-f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI146!GUID13d831Name Custom_ModelTransform‰posX `F@posY`Œù?posZ`+ÀrotX€b-P¿rotY 0¢?rotZ 1f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI147!GUIDd0d7d3Name Custom_ModelTransform‰posX€ E@posY þ‹ù?posZàpÀrotXÀô/P¿rotY fBž?rotZ ÿ0f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI148!GUID5478c0Name Custom_ModelTransform‰posX@ E@posY È‹ù?posZÀ.ÀrotXàtÚO¿rotY`Š˜?rotZÀe+f?scaleXffê?scaleYffê?scaleZffê?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?b@ Æ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshÖMeshURL!http://pastebin.com/raw/yL8Jjhz3DiffuseURL8https://www.dropbox.com/s/2xndsk443ltldq3/Tren.jpg?dl=1NormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI149JGUID0f3c9dName Custom_ModelTransform‰posX (è!ÀposY±V@posZ@Öß.ÀrotX`žɾrotYÀ€f@rotZþñ˜¾scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI150JGUID15294fName Custom_ModelTransform‰posX€+ÀposY€°V@posZÀrotX`‡+×¾rotY €f@rotZ ñÃ>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI151JGUIDca1d72Name Custom_ModelTransform‰posXÀõi'ÀposY °V@posZ`²Â-ÀrotX@[4Ö¾rotY €f@rotZ€1 ¾scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI152JGUID30ffc4Name Custom_ModelTransform‰posXÀ.ÀposY€°V@posZ€ûÿ ÀrotX…G̾rotY B€f@rotZÀ6ÌH>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI153JGUID8d3e80Name Custom_ModelTransform‰posX *5+ÀposYÀ°V@posZà–,ÀrotX F²¾rotYÀ€f@rotZ࡟Æ>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI154JGUIDfc6ea0Name Custom_ModelTransform‰posX-ÀposYÀ°V@posZ'ÀrotX`²Bâ¾rotY €f@rotZ ÷´¦>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI155JGUIDbbada3Name Custom_ModelTransform‰posX+ÀposY€°V@posZ$ÀrotX wï¾rotY €f@rotZÀA…>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI156JGUID361c22Name Custom_ModelTransform‰posXà&ÀposY€°V@posZÀÿÿ)ÀrotX yîÂ>rotY€f@rotZ@¼å¾scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI157äGUIDb6661fName Custom_ModelTransform‰posX d+#ÀposYà°V@posZÀ� 2ÀrotX€¡êà¾rotY`€f@rotZi¿>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescription›Moves forward 1 space automatically at the end of each Dividend Phase and income of companies present there increase by 1. CANNOT be developed by players.GMNotesAltLookAngle&xyzColorDiffuse&r ¿–é?gÀKCØ?b åû×?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI158JGUID078554Name Custom_ModelTransform‰posX'ÀposY`°V@posZ&ÀrotX ^ä¾rotY €f@rotZnòÉ>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI159JGUID320083Name Custom_ModelTransform‰posX"ÀposYÀ°V@posZ+ÀrotXà$ Ó¾rotY €f@rotZkÚ€>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI160JGUID848a1fName Custom_ModelTransform‰posX€)ÀposY`°V@posZ€(ÀrotXÀµ Á>rotY@€f@rotZà\aÈ>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI161JGUID7ac685Name Custom_ModelTransform‰posX€#ÀposYÀ°V@posZ€'ÀrotX CèÂ>rotY €f@rotZ 8ô©>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI162JGUID693351Name Custom_ModelTransform‰posX€$ÀposY€°V@posZ€#ÀrotXàRë¾rotY €f@rotZ £¥ª>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI163JGUID8b9d70Name Custom_ModelTransform‰posX€ ÀposY€°V@posZ€%ÀrotX ¬3¿¾rotY €f@rotZàì¼>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI164JGUID57edebName Custom_ModelTransform‰posX  ÀposY±V@posZ`ïM4ÀrotX õÐÓ>rotY €f@rotZ`1i¡¾scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI165JGUIDee3253Name Custom_ModelTransform‰posXÀposY`°V@posZ&ÀrotX€âÓ¾rotY €f@rotZ@÷ç¼>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI166JGUIDaaa55aName Custom_ModelTransform‰posXÀposY °V@posZ€(ÀrotX º¾rotY €f@rotZ ž»¥>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI167JGUID089ab3Name Custom_ModelTransform‰posXàÃVÀposY °V@posZÀdí,ÀrotX€ƒ=”>rotYà€f@rotZ€_©Ã>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI168JGUIDbaeaa3Name Custom_ModelTransform‰posXÀposY °V@posZ€)ÀrotX 7§¾rotY €f@rotZ Õ?`>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI169JGUID029c81Name Custom_ModelTransform‰posXÀƒ†ÀposY ±V@posZ`8w6ÀrotXÌ׿¾rotY`€f@rotZàM¤|>scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI170JGUIDebfdd7Name Custom_ModelTransform‰posX @KÀposY °V@posZ`iÝ-ÀrotX@± á>rotY€€f@rotZïó¤¾scaleXÀ33ç?scaleYÀ33ç?scaleZÀ33ç?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&r v%ê?g v%ê?b`EFæ?Tags0HouseLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomMeshçMeshURLihttps://steamusercontent-a.akamaihd.net/ugc/792009307529829815/A991E5D11C638DB9B6D78BFDCD4455D67E01C895/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUI171GUIDf1d8eeNameDeckTransform‰posX PG@posY€–vó?posZ�=4@rotX@Ä+H?rotY€?€f@rotZ€–x`¿scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsSidewaysCardDeckIDs0Ü1Ü2ÜCustomDeck?156FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812775/CD4025465F21A1E2699821DF17176C2976CC4EF5/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812775/CD4025465F21A1E2699821DF17176C2976CC4EF5/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUIContainedObjects? 0»GUIDac5053Name CardCustomTransform‰posX «pGÀposYàÀ,ð?posZfÐÀrotX@ ¶3?rotY B€f@rotZ€GÎ?scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDÜSidewaysCardCustomDeck?156FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812775/CD4025465F21A1E2699821DF17176C2976CC4EF5/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812775/CD4025465F21A1E2699821DF17176C2976CC4EF5/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI1»GUIDa21386Name CardCustomTransform‰posX ­pGÀposYÀ ðð?posZ€©ÏÀrotX€ ïD¿rotYÀ@€f@rotZ`ªûÌ?scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDÜSidewaysCardCustomDeck?156FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812775/CD4025465F21A1E2699821DF17176C2976CC4EF5/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812775/CD4025465F21A1E2699821DF17176C2976CC4EF5/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI2»GUID9f1761Name CardCustomTransform‰posX ¦pGÀposYàËTñ?posZ ©ÏÀrotX è7g¿rotY @€f@rotZ`‘æÈ?scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDÜSidewaysCardCustomDeck?156FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812775/CD4025465F21A1E2699821DF17176C2976CC4EF5/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812775/CD4025465F21A1E2699821DF17176C2976CC4EF5/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI172lGUID2c6c24NameDeckTransform‰posX@ÆG@posYÀ(±ó?posZ€h}#ÀrotX@ÇP?rotY 8€f@rotZÀ4-f¿scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsSidewaysCardDeckIDs/0@1@2@3@4@5@CustomDeck?166FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238813063/56AC2674BAFE22420ABDCEB6CB94295203856FEB/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238813063/56AC2674BAFE22420ABDCEB6CB94295203856FEB/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUIContainedObjectsy0»GUIDb9a269Name CardCustomTransform‰posX «G@posY g@posZ ˆ9ÀrotX@•M�?rotYàUŒf@rotZÀPñ`¿scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID@SidewaysCardCustomDeck?166FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238813063/56AC2674BAFE22420ABDCEB6CB94295203856FEB/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238813063/56AC2674BAFE22420ABDCEB6CB94295203856FEB/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI1»GUIDf2b880Name CardCustomTransform‰posX@�ŸG@posYæø@posZàf!9ÀrotX@`k?rotY xf@rotZà� [?scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID@SidewaysCardCustomDeck?166FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238813063/56AC2674BAFE22420ABDCEB6CB94295203856FEB/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238813063/56AC2674BAFE22420ABDCEB6CB94295203856FEB/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI2»GUID600241Name CardCustomTransform‰posX@‘²G@posY ’ž@posZ 6'9ÀrotXÀ9 €?rotY x†f@rotZÀ¿Õq¿scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID@SidewaysCardCustomDeck?166FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238813063/56AC2674BAFE22420ABDCEB6CB94295203856FEB/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238813063/56AC2674BAFE22420ABDCEB6CB94295203856FEB/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI3»GUID8a81b2Name CardCustomTransform‰posX ¾¹G@posY@œÁ@posZ@u%9ÀrotX€+…p?rotY@ûpf@rotZ [¶r?scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID@SidewaysCardCustomDeck?166FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238813063/56AC2674BAFE22420ABDCEB6CB94295203856FEB/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238813063/56AC2674BAFE22420ABDCEB6CB94295203856FEB/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI4»GUID6a7101Name CardCustomTransform‰posX@ÆG@posY Lðõ?posZ€h}#ÀrotX`ÆP?rotY8€f@rotZ€=-f¿scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID@SidewaysCardCustomDeck?166FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238813063/56AC2674BAFE22420ABDCEB6CB94295203856FEB/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238813063/56AC2674BAFE22420ABDCEB6CB94295203856FEB/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI5»GUID691668Name CardCustomTransform‰posX@ÆG@posY ×ô?posZ€h}#ÀrotX؆?rotY D€f@rotZ`°v@scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID@SidewaysCardCustomDeck?166FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238813063/56AC2674BAFE22420ABDCEB6CB94295203856FEB/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238813063/56AC2674BAFE22420ABDCEB6CB94295203856FEB/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI173¡GUIDd98f9aNameDeckTransform‰posX�G@posYµ�ó?posZ»8ÀrotX@�«L?rotY �€f@rotZHUc¿scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsSidewaysCardDeckIDs(0X1X2X3X4XCustomDeck>66FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812571/4B947EE4A66CDD2079A9A3ADBA17D3DB703215A4/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812571/4B947EE4A66CDD2079A9A3ADBA17D3DB703215A4/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUIContainedObjects¶0ºGUIDf736eaName CardCustomTransform‰posX€ ˆMÀposY â:ú?posZ¶é¿rotXc?rotY‡f@rotZÀˆ'{?scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDXSidewaysCardCustomDeck>66FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812571/4B947EE4A66CDD2079A9A3ADBA17D3DB703215A4/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812571/4B947EE4A66CDD2079A9A3ADBA17D3DB703215A4/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI1ºGUID8148e0Name CardCustomTransform‰posX ï”MÀposY§ìø?posZ å8ê¿rotXàŸ,^?rotY@¡}f@rotZ€eÉ{?scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDXSidewaysCardCustomDeck>66FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812571/4B947EE4A66CDD2079A9A3ADBA17D3DB703215A4/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812571/4B947EE4A66CDD2079A9A3ADBA17D3DB703215A4/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI2ºGUID2d6a09Name CardCustomTransform‰posX`›¢MÀposY`�¥ö?posZà—œ÷¿rotX€‘=Q¾rotYà¥f@rotZ b¾scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDXSidewaysCardCustomDeck>66FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812571/4B947EE4A66CDD2079A9A3ADBA17D3DB703215A4/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812571/4B947EE4A66CDD2079A9A3ADBA17D3DB703215A4/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI3ºGUID6b6130Name CardCustomTransform‰posX:�MÀposY€ \ù?posZˆ¨é¿rotX ËFa?rotYÀDvf@rotZÀË/{?scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDXSidewaysCardCustomDeck>66FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812571/4B947EE4A66CDD2079A9A3ADBA17D3DB703215A4/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812571/4B947EE4A66CDD2079A9A3ADBA17D3DB703215A4/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI4ºGUIDacbf86Name CardCustomTransform‰posX�G@posY�²ô?posZ»8ÀrotXž‚P?rotY 8€f@rotZÀd¿scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDXSidewaysCardCustomDeck>66FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812571/4B947EE4A66CDD2079A9A3ADBA17D3DB703215A4/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812571/4B947EE4A66CDD2079A9A3ADBA17D3DB703215A4/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI174U GUIDe5cf2fNameDeckTransform‰posX`eµ2@posY@`–@posZ@·H3ÀrotXkܽ>rotYRf@rotZ`?­>scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsSidewaysCardDeckIDs0�1�CustomDeck>46FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812039/13C3BF0D026C838883B3B8DD065868D1B89985FC/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812039/13C3BF0D026C838883B3B8DD065868D1B89985FC/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUIContainedObjects0ºGUID0211f0Name CardCustomTransform‰posXàýB0@posY7C@posZ ‚V4ÀrotXàgë3¿rotYRf@rotZ GM(¿scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID�SidewaysCardCustomDeck>46FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812039/13C3BF0D026C838883B3B8DD065868D1B89985FC/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812039/13C3BF0D026C838883B3B8DD065868D1B89985FC/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI1ºGUID9a265dName CardCustomTransform‰posX L0@posY_@posZÀY4ÀrotX è3¿rotY4f@rotZÀ"J(¿scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID�SidewaysCardCustomDeck>46FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812039/13C3BF0D026C838883B3B8DD065868D1B89985FC/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812039/13C3BF0D026C838883B3B8DD065868D1B89985FC/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI175[GUID87e89eName HandTriggerTransform‰posXÀ½ FÀposYÀ3Ø@posZàÞCÀrotXrotY€5!-¿rotZscaleX Æ 0@scaleY@scaleZ }›@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1r Zdë?g ™™¹?b a¸?aLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsFogColorRedLuaScriptLuaScriptStateXmlUI176\GUIDc92b45Name HandTriggerTransform‰posX@Ð4ÀposYÀ3Ø@posZ ØÞCÀrotX€rotYÀ±}v@rotZscaleX¦0@scaleY@scaleZ ÏV@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1r ?5¾?g€Âõà?bð?aLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsFogColorBlueLuaScriptLuaScriptStateXmlUI177 GUID4a7322NameCustom_Model_Infinite_BagTransform‰posX&@posY@ä×ï?posZ€@@rotXàúÖ¥¾rotYÀi€f@rotZ åiÐ>scaleX@Cï@scaleYàÜ›?scaleZ23 @NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?aLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsMaterialIndexÿÿÿÿMeshIndexÿÿÿÿCustomMeshèMeshURLjhttps://steamusercontent-a.akamaihd.net/ugc/1666858152071990826/9AD455F2CBAEC01B2CBCDDB8B6DC4CE48D14B545/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUIContainedObjectsÃ0»GUIDd0a0fbName CardCustomTransform‰posX Gj&@posY`Ζð?posZài«@@rotXÀSP™¾rotY Ëv@rotZ #ìÁ¾scaleXžjò?scaleYð?scaleZžjò?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0MoneyLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDÐSidewaysCardCustomDeck?206FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238861976/502B4798038A999F0E7880FC8B14E754097CCAB1/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238861976/502B4798038A999F0E7880FC8B14E754097CCAB1/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUIChildObjectsÃ0»GUIDd0a0fbName CardCustomTransform‰posX@MS>posYÀ}óZ½posZ¢Ú¬½rotXÀï»h½rotYà¡Vá¾rotZ`®Ò¾scaleX`¿ÚÝ?scaleY \@scaleZ`ìåÔ?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0MoneyLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDÐSidewaysCardCustomDeck?206FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238861976/502B4798038A999F0E7880FC8B14E754097CCAB1/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238861976/502B4798038A999F0E7880FC8B14E754097CCAB1/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI178 GUID06f562NameCustom_Model_Infinite_BagTransform‰posX5@posY ä×ï?posZ€@@rotXà=¡ˆ>rotY€Þf@rotZà‰�>scaleXÀµò@scaleYàÜ›?scaleZ23 @NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?aLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsMaterialIndexÿÿÿÿMeshIndexÿÿÿÿCustomMeshèMeshURLjhttps://steamusercontent-a.akamaihd.net/ugc/1666858152071990826/9AD455F2CBAEC01B2CBCDDB8B6DC4CE48D14B545/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUIContainedObjectsÃ0»GUIDf6e878Name CardCustomTransform‰posX5@posY€‡§ð?posZ€@@rotXL œ>rotY€‹+³?rotZÀ©ö²>scaleXžjò?scaleYð?scaleZžjò?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0MoneyLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID4SidewaysCardCustomDeck?216FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862213/71346EF831DA637123C13A263C6CEC620A234E19/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862213/71346EF831DA637123C13A263C6CEC620A234E19/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUIChildObjectsÃ0»GUIDf6e878Name CardCustomTransform‰posX€Ôïh¾posYÀ™:=posZ?\̽rotX@`¿1½rotY€è_ɾrotZÀ„pŸ;scaleX@¿ÚÝ?scaleY \@scaleZ`ìåÔ?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0MoneyLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID4SidewaysCardCustomDeck?216FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862213/71346EF831DA637123C13A263C6CEC620A234E19/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862213/71346EF831DA637123C13A263C6CEC620A234E19/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI179 GUIDe0d618NameCustom_Model_Infinite_BagTransform‰posXð?posY ä×ï?posZ€@@rotX p—W>rotY@C€f@rotZ€½yy¾scaleX Cï@scaleYàÜ›?scaleZ23 @NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?aLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsMaterialIndexÿÿÿÿMeshIndexÿÿÿÿCustomMeshèMeshURLjhttps://steamusercontent-a.akamaihd.net/ugc/1666858152071990826/9AD455F2CBAEC01B2CBCDDB8B6DC4CE48D14B545/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUIContainedObjectsÃ0»GUIDe00f3eName CardCustomTransform‰posXð?posY€‡§ð?posZ€@@rotX gŠh¾rotY`°v@rotZ ¨ö—>scaleXžjò?scaleYð?scaleZžjò?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0MoneyLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID˜SidewaysCardCustomDeck?226FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862438/D1CF0ACC0C1290540C18729AF3FE1FCC47619650/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862438/D1CF0ACC0C1290540C18729AF3FE1FCC47619650/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUIChildObjectsÃ0»GUIDe00f3eName CardCustomTransform‰posX`Mc¾posY à7=posZÀâ}›=rotXàQì+=rotY€E¹Õ>rotZ “,¥;scaleX`¿ÚÝ?scaleY \@scaleZ`ìåÔ?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0MoneyLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID˜SidewaysCardCustomDeck?226FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862438/D1CF0ACC0C1290540C18729AF3FE1FCC47619650/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862438/D1CF0ACC0C1290540C18729AF3FE1FCC47619650/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI180 GUIDe06783NameCustom_Model_Infinite_BagTransform‰posX5@posY ä×ï?posZ€@ÀrotXLûn¾rotY€Þf@rotZ ÿ~¾scaleXÀµò@scaleYàÜ›?scaleZ23 @NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?aLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsMaterialIndexÿÿÿÿMeshIndexÿÿÿÿCustomMeshèMeshURLjhttps://steamusercontent-a.akamaihd.net/ugc/1666858152071990826/9AD455F2CBAEC01B2CBCDDB8B6DC4CE48D14B545/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUIContainedObjectsÃ0»GUIDf6e878Name CardCustomTransform‰posX5@posY ‡§ð?posZ€@ÀrotX W¾q>rotYqÉ•?rotZ ˆC�¾scaleXžjò?scaleYð?scaleZžjò?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0MoneyLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID4SidewaysCardCustomDeck?216FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862213/71346EF831DA637123C13A263C6CEC620A234E19/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862213/71346EF831DA637123C13A263C6CEC620A234E19/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUIChildObjectsÃ0»GUIDf6e878Name CardCustomTransform‰posX€Ôïh¾posYÀ™:=posZ?\̽rotX@`¿1½rotY€è_ɾrotZÀ„pŸ;scaleX@¿ÚÝ?scaleY \@scaleZ`ìåÔ?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0MoneyLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID4SidewaysCardCustomDeck?216FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862213/71346EF831DA637123C13A263C6CEC620A234E19/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862213/71346EF831DA637123C13A263C6CEC620A234E19/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI181 GUID260026NameCustom_Model_Infinite_BagTransform‰posXð?posY ä×ï?posZ€@ÀrotX ¤ÃŽ>rotY C€f@rotZ Èp¾scaleX Cï@scaleYàÜ›?scaleZ23 @NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?aLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsMaterialIndexÿÿÿÿMeshIndexÿÿÿÿCustomMeshèMeshURLjhttps://steamusercontent-a.akamaihd.net/ugc/1666858152071990826/9AD455F2CBAEC01B2CBCDDB8B6DC4CE48D14B545/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUIContainedObjectsÃ0»GUIDe00f3eName CardCustomTransform‰posXð?posY€‡§ð?posZ€@ÀrotXŠÜ‚¾rotYà/ød?rotZ a ¾scaleXžjò?scaleYð?scaleZžjò?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0MoneyLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID˜SidewaysCardCustomDeck?226FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862438/D1CF0ACC0C1290540C18729AF3FE1FCC47619650/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862438/D1CF0ACC0C1290540C18729AF3FE1FCC47619650/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUIChildObjectsÃ0»GUIDe00f3eName CardCustomTransform‰posX`Mc¾posY à7=posZÀâ}›=rotXàQì+=rotY€E¹Õ>rotZ “,¥;scaleX`¿ÚÝ?scaleY \@scaleZ`ìåÔ?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0MoneyLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardID˜SidewaysCardCustomDeck?226FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862438/D1CF0ACC0C1290540C18729AF3FE1FCC47619650/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238862438/D1CF0ACC0C1290540C18729AF3FE1FCC47619650/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI182 GUID72ae63NameCustom_Model_Infinite_BagTransform‰posX&@posY@ä×ï?posZ€@ÀrotX@¢¯¾rotYÀi€f@rotZ !pÌ>scaleX@Cï@scaleYàÜ›?scaleZ23 @NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?aLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsMaterialIndexÿÿÿÿMeshIndexÿÿÿÿCustomMeshèMeshURLjhttps://steamusercontent-a.akamaihd.net/ugc/1666858152071990826/9AD455F2CBAEC01B2CBCDDB8B6DC4CE48D14B545/DiffuseURLNormalURLColliderURLConvexMaterialIndexTypeIndexCastShadowsLuaScriptLuaScriptStateXmlUIContainedObjectsÃ0»GUIDd0a0fbName CardCustomTransform‰posX ·Ö%@posYÀÙ–ð?posZ@h·@ÀrotXÀílS>rotY€­¹a¿rotZ yÉ’¾scaleXžjò?scaleYð?scaleZžjò?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0MoneyLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDÐSidewaysCardCustomDeck?206FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238861976/502B4798038A999F0E7880FC8B14E754097CCAB1/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238861976/502B4798038A999F0E7880FC8B14E754097CCAB1/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUIChildObjectsÃ0»GUIDd0a0fbName CardCustomTransform‰posX@MS>posYÀ}óZ½posZ¢Ú¬½rotXÀï»h½rotYà¡Vá¾rotZ`®Ò¾scaleX`¿ÚÝ?scaleY \@scaleZ`ìåÔ?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0MoneyLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDÐSidewaysCardCustomDeck?206FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238861976/502B4798038A999F0E7880FC8B14E754097CCAB1/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238861976/502B4798038A999F0E7880FC8B14E754097CCAB1/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI183iGUID5e6aabName Custom_TokenTransform‰posX ÙK6ÀposY@—$ @posZ`î{ÀrotX ~°ì>rotY€Áå]@rotZ@cë?scaleX€2áï?scaleYð?scaleZ€2áï?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomImageImageURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567239330776/E73DC0E6C62F66D90A499BE3E77315C437ABB387/ImageSecondaryURLImageScalarð?WidthScaleCustomTokenKThickness ™™É?MergeDistancePixels.@StandUpStackableLuaScriptLuaScriptStateXmlUIPhysicsMaterialrStaticFrictionð?DynamicFrictionð?BouncinessFrictionCombineBounceCombineRigidbodyCMassÀÝúï?Drag ™™¹?AngularDrag@�@UseGravityJointHinge*UseLimitsLimits�minBouncemaxBounceminmaxbouncinessbounceMinVelocity ™™É?contactDistanceUseMotorMotor7targetVelocityforcefreeSpinUseSpringSpring=springdampertargetPositionConnectedBodyGUID674887EnableCollisionAxis&xyð?zAnchor&xyzConnectedAnchor&x ÷l@y@·ïã?z@÷ú÷?BreakForceðBreakTorgueð184iGUID9116cdName Custom_TokenTransform‰posXÀ6K6ÀposYà—$ @posZà|Z*ÀrotX@�ˆÔ>rotY ©^@rotZ€l‚ð>scaleX€2áï?scaleYð?scaleZ€2áï?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomImageImageURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567239330776/E73DC0E6C62F66D90A499BE3E77315C437ABB387/ImageSecondaryURLImageScalarð?WidthScaleCustomTokenKThickness ™™É?MergeDistancePixels.@StandUpStackableLuaScriptLuaScriptStateXmlUIPhysicsMaterialrStaticFrictionð?DynamicFrictionð?BouncinessFrictionCombineBounceCombineRigidbodyCMassÀÝúï?Drag ™™¹?AngularDrag@�@UseGravityJointHinge*UseLimitsLimits�minBouncemaxBouncerê.8minmaxbouncinessbounceMinVelocity ™™É?contactDistanceUseMotorMotor7targetVelocityforcefreeSpinUseSpringSpring=springdampertargetPositionConnectedBodyGUID674887EnableCollisionAxis&xyð?zAnchor&xyzConnectedAnchor&x 0l@y ·ïã?z®7@BreakForceðBreakTorgueð185iGUIDf7d6e6Name Custom_TokenTransform‰posX@©M6ÀposY@˜$ @posZ¶Š5ÀrotXà;“?rotY`^@rotZ`³ù>scaleX€2áï?scaleYð?scaleZ€2áï?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomImageImageURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567239330776/E73DC0E6C62F66D90A499BE3E77315C437ABB387/ImageSecondaryURLImageScalarð?WidthScaleCustomTokenKThickness ™™É?MergeDistancePixels.@StandUpStackableLuaScriptLuaScriptStateXmlUIPhysicsMaterialrStaticFrictionð?DynamicFrictionð?BouncinessFrictionCombineBounceCombineRigidbodyCMassÀÝúï?Drag ™™¹?AngularDrag@�@UseGravityJointHinge*UseLimitsLimits�minBouncemaxBounce8/8minmaxbouncinessbounceMinVelocity ™™É?contactDistanceUseMotorMotor7targetVelocityforcefreeSpinUseSpringSpring=springdampertargetPositionConnectedBodyGUID674887EnableCollisionAxis&xyð?zAnchor&xyzConnectedAnchor&x`3o@y ¶ïã?z€Uƒ@BreakForceðBreakTorgueð186^GUID7ac8f1Name HandTriggerTransform‰posXÀŒFÀposYí@posZ/ÒC@rotX€rotY€8 —?rotZscaleX€ný/@scaleY@scaleZ€ÝÈ@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1r€Âõì?g€j¼ì?b@Æ?aLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsFogColorYellowLuaScriptLuaScriptStateXmlUI187õGUIDc1dcefName Custom_PDFTransform‰posX@’tÕ?posYZ¸*@posZ œ:O@rotXà!Ö@@rotY@Ç‚f@rotZ4rÂ?scaleXà7&@scaleYð?scaleZà7&@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCustomPDF­PDFUrljhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238837876/AE35BF5DFCA3E3C6B9427D3F512BDF0570BF9C57/PDFPasswordPDFPagePDFPageOffsetLuaScriptLuaScriptStateXmlUI188Ó¥GUID6714adNameCounterTransform‰posX€A@posY\ºí?posZÀÿÿ6ÀrotX`(1r>rotYÀ� T¿rotZÀ%°¾scaleX€ÿÿû?scaleY€ÿÿû?scaleZ€ÿÿû?NicknameMoneyDescription 2,5,10,25GMNotesAltLookAngle&xyzColorDiffuse&rs“È?g€—næ?b@�Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCountervalueLuaScriptq£function onLoad(str) --In code settings-- invertcoin=false --old negative value is now positive and old positive value is now negative coinzero=-2 --0 > toggle when beond zero, -1 > zero is negative, 1 > zero is positive, 2 > toggle when reached zero, -2 > zero is special autoconnect=true --allow autoconnecting by putting counters next to each other howfaraconn=0.6 --how far autoconnect works (object scale affects this) showcalcround=true --show autocalculation list on hover --End of settings--- savechanged=false local start=false SETTINGS_POS=string.find(self.script_code,"--End of settings---") self.setVar("SETTINGS_POS",SETTINGS_POS) if str != "" and str != nil then local data=JSON.decode(str) for name, info in pairs(data) do if name == "extendCounterObjs" then if type(info).."" == "table" then if #info > 1 then extendCounterObjs={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(extendCounterObjs,obj) end end if #extendCounterObjs < 2 then extendCounterObjs=nil end end end end if name == "extendCounterCoin" then local obj=getObjectFromGUID(info) if obj then extendCounterCoin=obj end end if name == "autoCalculateList" then if type(info).."" == "table" then if #info > 2 then autoCalculateList={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(autoCalculateList,obj) end end if #autoCalculateList < 3 then autoCalculateList=nil else start=true end end end end end end self.setVar("whatIAm","Counter") self.setVar("Supports_getTotalValue",true) self.setVar("whatIAmSpecfically","[finmod]Advanced Counter Mark II") watchDesc() updateContextMenu() if start then autoCalculateActive=false; autocalcOperation(); end end function onSave() local objs={} local autol={} local rettab={} local coin if savechanged then if extendCounterCoin then coin=extendCounterCoin.getGUID() end if type(extendCounterObjs).."" == "table" then for _, obj in ipairs(extendCounterObjs) do if obj then table.insert(objs,obj.getGUID()) end end end if type(autoCalculateList).."" == "table" then for _, obj in ipairs(autoCalculateList) do if obj then table.insert(autol,obj.getGUID()) end end end if #objs > 1 then rettab["extendCounterObjs"]=objs end if coin then rettab["extendCounterCoin"]=coin end if #autol > 2 then rettab["autoCalculateList"]=autol end savechanged=false return JSON.encode(rettab) else return self.script_state end end function getAnyVar(tab) return _G[tab[1]] end function setAnyVar(tab) _G[tab[1]]=tab[2] end function onHover(col) if autoCalculateList != nil and showcalcround then local showme={ color=Color(1,1,1), thickness=0.1, rotation=Vector(0,0,0), points={} } local pos=self.getPosition()+Vector(0,0.5,0) local ipos=self.getPosition()-Vector(0,1.5,0) local prevvec=vectorToLocal(pos,self.getPosition(),self.getScale(),self.getRotation()) local list={} i=#autoCalculateList while i > 0 do showme.color=Color(1,1,1):lerp(Color(0,0,1),(#autoCalculateList-i)/(#autoCalculateList-1)) table.insert(list,makecopytab(showme,1)) list[#autoCalculateList-i+1].points[1]=prevvec local obj=autoCalculateList[i] list[#autoCalculateList-i+1].points[2]=vectorToLocal(obj.getPosition(),ipos,self.getScale()*Vector(3,3,3),self.getRotation()) prevvec=list[#autoCalculateList-i+1].points[2] i=i-1 end self.setVectorLines(list) Wait.time(function() self.setVectorLines() end, 3.0) end end function onPickUp(color) if type(extendCounterObjs).."" == "table" then local amount=#extendCounterObjs local selob=Player[color].getSelectedObjects() if selob then if #selob == amount then for i=1, amount do local test = false for x=1, amount do if selob[i] == extendCounterObjs[x] then test=true end end if test then return end end end end for i, obj in ipairs(extendCounterObjs) do if obj then if string.sub(obj.script_code,obj.getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or obj.getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then obj.call("extflash",{nil}) obj.call("updateContextMenu") else local guid=obj.getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end end end end printToAll("broke connection of ".. amount .." counters.") end end function onDrop(color) startChecking() end function startChecking() if autoconnect then preCheck(os.time()+3) end end function preCheck(secs) if os.time() < secs then if not self.resting and checkWait == nil then checkWait=Wait.time(function() preCheck(secs) end,0.1) else checkWait=nil checkConnections() end else checkWait=nil end end function checkConnections() local finallist={self} local bd=self.getBounds() local scale=self.getScale() local x=bd.size.x / 2.0 local rot=self.getRotation() local left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) local right=Vector()-left local cpos=self.getPosition() local tmppos=cpos local test=true while test do local list=findInRadiusBy(tmppos+left,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,list[1]) else test=false end end tmppos=cpos test=true while test do local list=findInRadiusBy(tmppos+right,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 right=Vector(x+(howfaraconn+0.5)*scale.x,-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,1,list[1]) else test=false end end if #finallist <= 1 then return end local coin=extendCounterCoin for i=1,#finallist do if string.sub(finallist[i].script_code,finallist[i].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or finallist[i].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then finallist[i].call("extflash",{finallist}) if coin then finallist[i].call("scriptcoin",{coin,invertcoin,coinzero}) end else local guid=finallist[i].getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end end printToAll("Connected ".. #finallist .." counters.") end function watchDesc() if savedDesc != self.getDescription() then local a,b=readDesc() createButtons(a,b) savedDesc=self.getDescription() end if savedTint != self.getColorTint() then local a,b=readDesc() createButtons(a,b) savedTint=self.getColorTint() end Wait.time(watchDesc,0.5) end function updateContextMenu() self.clearContextMenu() self.addContextMenuItem("extend counter",extendc) if extendCounterObjs != nil then self.addContextMenuItem("clear",function() local a,minus,c=getTotalValue(); if coinzero == -1 then minus=true elseif coinzero == 1 then minus=false elseif coinzero == 2 then minus=not minus end setTotalValue({0,minus}) end) end self.addContextMenuItem("make autocalc",autocalc) savechanged=true end function extendc(col) if col == nil then extendCounterObjs=nil return end extendCounterObjs=Player[col].getSelectedObjects() extendCounterCoin=nil if extendCounterObjs != nil then if #extendCounterObjs <= 1 then extendCounterObjs=nil elseif #extendCounterObjs >= 2 then -- if self != extendCounterObjs[1] then -- printToAll("[ff0000]ERROR:[-]select smallest counter first, and from smallest counter right click menu.") -- return -- end if extendCounterObjs[i].type.."" != "Counter" then local i=1 while i <= #extendCounterObjs do if string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) and extendCounterObjs[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then local typetest=extendCounterObjs[i].type.."" == "Counter" or (extendCounterObjs[i].getVar("whatIAm") == "Counter") if i == 2 then if i == #extendCounterObjs then extendCounterCoin=extendCounterObjs[#extendCounterObjs] extendCounterObjs=nil return end elseif i == #extendCounterObjs and not typetest then log("LinkkingCounters:we assume this is coin (negitve display)") extendCounterCoin=extendCounterObjs[#extendCounterObjs] table.remove(extendCounterObjs) elseif typetest then printToAll("[ff0000]ERROR:[-]Unknown counter (possibly unexpected behaviour).") else table.remove(extendCounterObjs,i) i=i-1 end elseif string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) then printToAll("[ff0000]ERROR:[-]Counters not the same version (Advanced Counter Mark II) (possibly unexpected behaviour).") end i=i+1 end if #extendCounterObjs >= 2 then extendCounterObjs[1].call("scriptext",{extendCounterObjs,1}) end for i=1, #extendCounterObjs do if extendCounterObjs[i] != self then extendCounterObjs[i].call("scriptcoin",{extendCounterCoin,invertcoin,coinzero}) end end end end updateContextMenu() end function autocalc(col) savechanged=true autoCalculateList=nil if col == nil then return end autoCalculateList=Player[col].getSelectedObjects() Player[col].clearSelectedObjects() if autoCalculateList == nil then return end local i=1 while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i != #autoCalculateList then local test=isOperator(autoCalculateList[i].getName()) if not test then test=isOperator(autoCalculateList[i].getDescription()) end if not test then printToAll("[ff0000]ERROR:[-]autocalc: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) else local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,0),0.45) end, i*0.3+0.7) end else if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then log("non Advanced Counter Mark II detected (or too old version). "..i) else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then log("other version of Advanced Counter Mark II detected. "..i) else log("[00ff00]OK:[-]same version of Advanced Counter Mark II detected. "..i) end end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) end i=i+1 end log(autoCalculateList) table.remove(autoCalculateList) -- remove self if #autoCalculateList > 1 and ((#autoCalculateList % 2) == 1) then autoCalculateActive=false autocalcOperation() else printToAll("[ff0000]ERROR:[-] ".. #autoCalculateList .." long list failed (dropped). Select odd number of objects, starting from counter, then finally select counter to display the value (paired number of selected objects).") autoCalculateList=nil end end function autocalcOperation() if autoCalculateList != nil then if not autoCalculateActive then autoCalculateActive=true local i=1 local lastop local mycalc,myminus=0,false while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i == #autoCalculateList then printToAll("[ff0000]ERROR:[-]autocalcOperation: last one cannot be operator.") end local test=isOperator(autoCalculateList[i].getName()) if test then lastop=autoCalculateList[i].getName() else test=isOperator(autoCalculateList[i].getDescription()) if test then lastop=autoCalculateList[i].getDescription() else printToAll("[ff0000]ERROR:[-]autocalcOperation: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end end else local var,minus,index if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" and not autoCalculateList[i].getVar("Supports_getTotalValue") then var=autoCalculateList[i].getValue() minus=var < 0 else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) else var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) end end if i == 1 then mycalc=math.abs(var) myminus=minus else mycalc,myminus=rawCalcOperation(lastop,mycalc,var,myminus,minus) end end i=i+1 end setTotalValue({mycalc,myminus}) autoCalculateActive=false autoCalculateWait=Wait.time(autocalcOperation,1.0) end end end function debugme() log(extendCounterObjs) log(extendCounterCoin) if autoCalculateList != nil then for i, obj in ipairs(autoCalculateList) do local guid=obj.getGUID() local times=#autoCalculateList Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 0) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 1) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 2) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 3) end else log("nil") end local a,b=readDesc() log(a) log(b) end function extflash(tab) if tab[1] == nil then for i=1, 7 do Wait.time(function() self.highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end else for i=1, 7 do Wait.time(function() self.highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end extset(tab) end function extset(tab) extendCounterObjs=tab[1] updateContextMenu() end function scriptext(tab) if #tab[1] >= tab[2] then extendCounterObjs=tab[1] if #tab[1] > tab[2] then if string.sub(tab[1][tab[2]+1].script_code,tab[1][tab[2]+1].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or tab[1][tab[2]+1].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then tab[1][tab[2]+1].call("scriptext",{tab[1],tab[2]+1}) else -- end end updateContextMenu() end end function scriptcoin(coin) extendCounterCoin=coin[1] if #coin > 1 then if coin[2] != nil then invertcoin=coin[2] end if #coin > 2 then if coin[3] != nil then coinzero=coin[3] end end end end function createButtons(buttonlist,whatlist) self.clearButtons() local bgcol=self.getColorTint() local test=(bgcol.r * 0.3 + bgcol.r * 0.3 * (1-bgcol.g) + bgcol.g + bgcol.b * 0.4 > 0.925) local txtcol=test and Color(1,1,1) or Color(0,0,0) local buttcol=test and Color(0.2,0.2,0.2) or Color(0.8,0.8,0.8) local butthov=Color(0.5,0.5,0.5) --[[ self.createButton({ click_function=nil, function_owner=self, label=" ", position=Vector(0,0.2,-0.4-(math.ceil(#buttonlist/2)*0.08-0.08)), scale=Vector(0.1,1,0.1), width=4500, height=800*math.ceil(#buttonlist/2)+200, color={bgcol.r,bgcol.g,bgcol.b}, hover_color={bgcol.r,bgcol.g,bgcol.b}, press_color={bgcol.r,bgcol.g,bgcol.b} })]] local buttonorginpos=Vector(0.32,0.201,-0.41) local frame={ click_function="button", function_owner=self, label=" ", font_size=400, position=buttonorginpos, rotation=Vector(0,180,0), scale=Vector(0.1,1,0.1), width=1000, height=600, color={buttcol.r,buttcol.g,buttcol.b}, hover_color={butthov.r,butthov.g,butthov.b}, press_color={butthov.r,butthov.g,butthov.b}, font_color={txtcol.r,txtcol.g,txtcol.b} } local i=1 local slot=0 local line=0 local halfi=0 local function slothand(slot,lablen) if lablen == 1 then if slot == 0 then return 0 elseif slot == 1 then return -0.21 elseif slot == 2 then return -0.43 elseif slot == 3 then return -0.64 end elseif lablen == 2 then if slot == 0 then return -0.105 elseif slot == 1 then return -0.32 elseif slot == 2 then return -0.535 end elseif lablen == 3 then if slot == 0 then return -0.21 elseif slot == 1 then return -0.43 end elseif lablen == 4 then return -0.32 end end while i <= #buttonlist do local lastone=i == #buttonlist local curra,currb local test=whatlist[i] == "" if test then curra,currb=makecopytab(frame,1),makecopytab(frame,1) else curra=makecopytab(frame,1) end local formatted local formtype=numinter(buttonlist[i],nil,true) if formtype == "1" then formatted=string.format("%d",buttonlist[i]) else formatted=buttonlist[i] end local poslab=(test and "+" or (whatlist[i]))..formatted local neglab="-"..formatted local lablen=math.ceil(string.len(poslab)/4.5) if lablen > 4 then lablen=4; end curra.click_function=curra.click_function..(i-1+halfi)*2 if test then currb.click_function=currb.click_function..(i-1+halfi)*2+1 attachIndex("button",(i-1+halfi)*2) attachIndex("button",(i-1+halfi)*2+1) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=neglab if slot+lablen > 4 then line=line+1; slot=0; end currb.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) currb.width=lablen * currb.width currb.label=poslab self.createButton(curra) self.createButton(currb) else attachIndex("button",(i-1+halfi)*2) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=poslab self.createButton(curra) halfi=halfi-0.5 end i=i+1 end end function dummy() end function attachIndex(click_function, index) -- function to create multiple versions of function local fn_name = click_function .. index _G[fn_name] = function(obj, player_color, alt_click) _G[click_function](obj, player_color, alt_click, index) end return fn_name end function getTotalValue() if extendCounterObjs == nil then if extendCounterCoin == nil then local var=tonumber(self.getValue()) or 0 return var,var < 0,1 else local minus local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end return (minus and -math.abs(tonumber(self.getValue()) or 0) or math.abs(tonumber(self.getValue()) or 0)),minus,1 end else local meCounterIndex local i=1 while i <= #extendCounterObjs do if extendCounterObjs[i] == self then meCounterIndex=i end if extendCounterObjs[i] == nil then log("linked counter operation, counter "..i.." removed.") table.remove(extendCounterObjs,i) i=i-1 end i=i+1 end if #extendCounterObjs <= 1 then printToAll("[ff0000]ERROR:[-]Only one counter left, and started linkked counter operation.") extendCounterObjs=nil updateContextMenu() return getTotalValue() end if meCounterIndex == nil then printToAll("[ff0000]ERROR:[-]did not find index of counter."); return nil,nil,nil end local var=0 i=#extendCounterObjs local minus if extendCounterCoin == nil then minus=false else local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end end while i >= 1 do var=math.abs(tonumber(extendCounterObjs[i].getValue()) or 0) + var * 10000 i=i-1 end return (minus and -var or var),minus,meCounterIndex end end function setTotalValue(tab) local var,minus if type(tab).."" == "table" then if #tab >= 1 then var=tab[1] end if #tab >= 2 then minus=tab[2] end else log("setTotalValue:not a table") end if extendCounterObjs == nil then if minus == nil then minus=var < 0 end if minus and extendCounterCoin == nil then var=math.abs(var) % (minus and 1000 or 10000) elseif extendCounterCoin != nil then var=math.abs(var) % 10000 local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end if extendCounterCoin == nil then self.setValue(minus and -var or var) else self.setValue(var) end else if minus == nil then minus=var < 0 end var=var % math.pow(10000,#extendCounterObjs) if minus and extendCounterCoin == nil then var=math.pow(10000,#extendCounterObjs) - var elseif extendCounterCoin != nil then local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end i=#extendCounterObjs while i >= 1 do extendCounterObjs[i].setValue(math.floor(var/math.pow(10000,i-1)) % 10000) i=i-1 end end end function button(obj, col, alt_click, index) local list=self.getButtons() local var,minus,meCounterIndex=getTotalValue() local currlabel=list[index+1].label local oplett=string.sub(currlabel,1,1) local addable=numinter(string.sub(currlabel,2),0) var,minus=rawCalcOperation(oplett,var,addable * math.pow(10000,meCounterIndex-1),minus,false) setTotalValue({var,minus}) end function wrapCalcOperation(tab) local a,b,c,d,e if type(tab).."" == "table" then if #tab >= 1 then a=tab[1] end if #tab >= 2 then b=tab[2] end if #tab >= 3 then c=tab[3] end if #tab >= 4 then d=tab[4] end if #tab >= 5 then e=tab[5] end for name, item in pairs(tab) do if name == "oplett" then a=item elseif name == "var" then b=item elseif name == "addable" then c=item elseif name == "minus" then d=item elseif name == "addmeg" then e=item end end local var,minus=rawCalcOperation(a,b,c,d,e) return var,minus else log("wrapCalcOperation:not a table") return nil,nil end end function rawCalcOperation(oplett,var,addable,minus,addneg) if minus == nil then if var < 0 then minus=true else minus=false end end if addneg == nil then if addable < 0 then addneg=true else addneg=false end end if isOperator(oplett) then -- if oplett == "+" or oplett == "-" then -- if oplett == "-" and minus then -- oplett="+" -- elseif oplett == "+" and minus then -- oplett="-" -- end -- end else log("rawCalcOperation:Wrong operator") end if minus == addneg then local pah if oplett == "-" and minus then oplett = "+" end pah,var=isOperator(oplett,var,addable) else local pah if oplett == "-" then oplett = "+" elseif oplett == "+" then oplett = "-" end if minus then -- addable positive, var negative pah,var=isOperator(oplett,var,addable) else -- addable negative, var positive pah,var=isOperator(oplett,var,addable) end end if coinzero == 0 then if var < 0 then minus=not minus end elseif coinzero == -1 then if var < 0 then minus=not minus elseif 0 == var then minus=true end elseif coinzero == 1 then if var < 0 then minus=not minus elseif 0 == var then minus=false end elseif coinzero == 2 then if var >= 0 then minus=not minus end elseif coinzero == -2 then if var < 0 then minus=not minus end end return math.abs(var),minus end function isOperator(str,a,b) if type(str).."" == "string" then if string.len(str) == 1 then if type(a).."" == "number" and type(b).."" == "number" then a,b=math.abs(a),math.abs(b) if str == "+" then return true,a+b elseif str == "-" then return true,a-b elseif str == "*" then local pa,pb=a%100000000,b%100000000 local ba,bb=(a-pa)/100000000,(b-pb)/100000000 return true,pa*pb + ((ba*pb)%100000000)*100000000 + ((bb*pa)%100000000)*100000000 elseif str == "/" then return true,math.floor(a/b) elseif str == "&" then local ta,tb=a,b local i=0 local num=0 while ta != 0 and tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == cb and ca == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "|" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == 1 or cb == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "^" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if (ca == 1 and cb == 0) or (ca == 0 and cb == 1) then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "%" then return true,a%b elseif str == "<" then if b == 0 then return true,a end return true,a * math.pow(2,b) elseif str == ">" then if b == 0 then return true,a end return true,math.floor(a / math.pow(2,b)) elseif str == "p" then return true,math.floor(math.pow(a,b)) elseif str == "r" then return true,math.floor(math.pow(a,1.0/b)) end else if str == "+" then return true end if str == "-" then return true end if str == "*" then return true end if str == "/" then return true end if str == "&" then return true end if str == "|" then return true end if str == "^" then return true end if str == "%" then return true end if str == "<" then return true end if str == ">" then return true end if str == "p" then return true end if str == "r" then return true end end else log("isOperator:only one mark accepted ("..str..")") end else log("isOperator:only strings (of one character) accepted") end return false end function numinter(num,default,indentify) if type(num).."" == "number" then return num end if type(num).."" == "string" then local check="0123456789abcdefghijklmnopqrstuvwxyz" local out=nil if string.sub(num,1,1) == "0" then --hex or octaconal if string.sub(num,2,2) == "x" then --hex (base 16) if indentify then return "x" end local i=3 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:hex:not regonized character (".. c ..")"); elseif f >= 1 and f <= 16 then out=(out or 0) * 16 + f - 1 else log("numinter:hex:character out of bounds (".. (f-1) .. ")") end i=i+1 end else --octaconal (base 8) if indentify then return "0" end local i=2 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:octa:not regonized character (".. c ..")"); elseif f >= 1 and f <= 8 then out=(out or 0) * 8 + f - 1 else log("numinter:octa:character out of bounds (".. (f-1) .. "),(".. c ..")") end i=i+1 end end else if indentify then return "1" end out=tonumber(num) end if out == nil then return default else return out end end return default end function readDesc() local buttonlist={} local whatlist={} local desc=self.getDescription() or "" local txtstep=string.find(desc,",",1,true) if txtstep != nil then local prevstep repeat local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),txtstep-1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end prevstep=txtstep txtstep=string.find(desc,",",txtstep+1,true) until txtstep == nil or txtstep == string.len(desc) if textstep == nil then local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),string.len(desc)) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end elseif string.len(desc) > 0 then local poper=string.sub(desc,1,1) local test=isOperator(poper) local num=string.sub(desc,test and 2 or 1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end return buttonlist,whatlist end function makecopytab(tab,depth) local mydepth=depth or 0 if mydepth < 0 then log("this should not have been called. makecopytab") log(tab) return nil end local newtab={} if type(tab).."" == "table" then for x, val in pairs(tab) do if type(x).."" == "number" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then table.insert(newtab,x,Vector(tab[x])) else if mydepth > 0 then table.insert(newtab,x,makecopytab(tab[x],mydepth-1)) else table.insert(newtab,x,{}) end end else table.insert(newtab,x,tab[x]) end elseif type(x).."" == "string" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then newtab[x]=Vector(tab[x]) else if mydepth > 0 then newtab[x]=makecopytab(tab[x],mydepth-1) else newtab[x]={} end end else newtab[x]=tab[x] end end end else return tab end return newtab end function vectorRotate(vec,rot) return vec:rotateOver("z",rot.z):rotateOver("x",rot.x):rotateOver("y",rot.y) end function vectorIRotate(vec,rot) return vec:rotateOver("y",rot.y):rotateOver("x",rot.x):rotateOver("z",rot.z) end function vectorToLocal(target,objvec,objscale,objrot) local copy=Vector(target) copy=copy-(objvec or Vector(0,0,0)) copy=vectorIRotate(copy,(objrot or Vector(0,0,0)):inverse()) local tmp=objscale or Vector(1,1,1) copy=Vector(copy.x / tmp.x,copy.y / tmp.y, copy.z / tmp.z) return copy end function wrapVectorToLocal(tab) return vectorToLocal(tab[1],tab[2],tab[3],tab[4]) end function findInRadiusBy(pos, radius, func, debug) --by MrStump https://steamcommunity.com/sharedfiles/filedetails/?id=752690530&searchtext=lua --if DEBUG then log(" findInRadiusBy(): just called") end local radius = (radius or 1) local objList = Physics.cast({ origin=pos, direction={0,1,0}, type=2, size={radius,radius,radius}, max_distance=0, debug=(debug or false) }) local refinedList = {} for _, obj in ipairs(objList) do if func == nil then if obj.hit_object.type != "Surface" then -- Finaryman Mod table.insert(refinedList, obj.hit_object) end else if func(obj.hit_object) and obj.hit_object.type != "Surface" then --Finaryman Mod table.insert(refinedList, obj.hit_object) end end end return refinedList endLuaScriptState[]XmlUI189Ó¥GUID36ea67NameCounterTransform‰posX€A@posY \ºí?posZÀÿÿÀrotX uc‘¾rotYÀß@T¿rotZÀ½i†¾scaleX€ÿÿû?scaleY€ÿÿû?scaleZ€ÿÿû?NicknameMoneyDescription 2,5,10,25GMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?bÀÆ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCountervalueLuaScriptq£function onLoad(str) --In code settings-- invertcoin=false --old negative value is now positive and old positive value is now negative coinzero=-2 --0 > toggle when beond zero, -1 > zero is negative, 1 > zero is positive, 2 > toggle when reached zero, -2 > zero is special autoconnect=true --allow autoconnecting by putting counters next to each other howfaraconn=0.6 --how far autoconnect works (object scale affects this) showcalcround=true --show autocalculation list on hover --End of settings--- savechanged=false local start=false SETTINGS_POS=string.find(self.script_code,"--End of settings---") self.setVar("SETTINGS_POS",SETTINGS_POS) if str != "" and str != nil then local data=JSON.decode(str) for name, info in pairs(data) do if name == "extendCounterObjs" then if type(info).."" == "table" then if #info > 1 then extendCounterObjs={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(extendCounterObjs,obj) end end if #extendCounterObjs < 2 then extendCounterObjs=nil end end end end if name == "extendCounterCoin" then local obj=getObjectFromGUID(info) if obj then extendCounterCoin=obj end end if name == "autoCalculateList" then if type(info).."" == "table" then if #info > 2 then autoCalculateList={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(autoCalculateList,obj) end end if #autoCalculateList < 3 then autoCalculateList=nil else start=true end end end end end end self.setVar("whatIAm","Counter") self.setVar("Supports_getTotalValue",true) self.setVar("whatIAmSpecfically","[finmod]Advanced Counter Mark II") watchDesc() updateContextMenu() if start then autoCalculateActive=false; autocalcOperation(); end end function onSave() local objs={} local autol={} local rettab={} local coin if savechanged then if extendCounterCoin then coin=extendCounterCoin.getGUID() end if type(extendCounterObjs).."" == "table" then for _, obj in ipairs(extendCounterObjs) do if obj then table.insert(objs,obj.getGUID()) end end end if type(autoCalculateList).."" == "table" then for _, obj in ipairs(autoCalculateList) do if obj then table.insert(autol,obj.getGUID()) end end end if #objs > 1 then rettab["extendCounterObjs"]=objs end if coin then rettab["extendCounterCoin"]=coin end if #autol > 2 then rettab["autoCalculateList"]=autol end savechanged=false return JSON.encode(rettab) else return self.script_state end end function getAnyVar(tab) return _G[tab[1]] end function setAnyVar(tab) _G[tab[1]]=tab[2] end function onHover(col) if autoCalculateList != nil and showcalcround then local showme={ color=Color(1,1,1), thickness=0.1, rotation=Vector(0,0,0), points={} } local pos=self.getPosition()+Vector(0,0.5,0) local ipos=self.getPosition()-Vector(0,1.5,0) local prevvec=vectorToLocal(pos,self.getPosition(),self.getScale(),self.getRotation()) local list={} i=#autoCalculateList while i > 0 do showme.color=Color(1,1,1):lerp(Color(0,0,1),(#autoCalculateList-i)/(#autoCalculateList-1)) table.insert(list,makecopytab(showme,1)) list[#autoCalculateList-i+1].points[1]=prevvec local obj=autoCalculateList[i] list[#autoCalculateList-i+1].points[2]=vectorToLocal(obj.getPosition(),ipos,self.getScale()*Vector(3,3,3),self.getRotation()) prevvec=list[#autoCalculateList-i+1].points[2] i=i-1 end self.setVectorLines(list) Wait.time(function() self.setVectorLines() end, 3.0) end end function onPickUp(color) if type(extendCounterObjs).."" == "table" then local amount=#extendCounterObjs local selob=Player[color].getSelectedObjects() if selob then if #selob == amount then for i=1, amount do local test = false for x=1, amount do if selob[i] == extendCounterObjs[x] then test=true end end if test then return end end end end for i, obj in ipairs(extendCounterObjs) do if obj then if string.sub(obj.script_code,obj.getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or obj.getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then obj.call("extflash",{nil}) obj.call("updateContextMenu") else local guid=obj.getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end end end end printToAll("broke connection of ".. amount .." counters.") end end function onDrop(color) startChecking() end function startChecking() if autoconnect then preCheck(os.time()+3) end end function preCheck(secs) if os.time() < secs then if not self.resting and checkWait == nil then checkWait=Wait.time(function() preCheck(secs) end,0.1) else checkWait=nil checkConnections() end else checkWait=nil end end function checkConnections() local finallist={self} local bd=self.getBounds() local scale=self.getScale() local x=bd.size.x / 2.0 local rot=self.getRotation() local left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) local right=Vector()-left local cpos=self.getPosition() local tmppos=cpos local test=true while test do local list=findInRadiusBy(tmppos+left,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,list[1]) else test=false end end tmppos=cpos test=true while test do local list=findInRadiusBy(tmppos+right,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 right=Vector(x+(howfaraconn+0.5)*scale.x,-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,1,list[1]) else test=false end end if #finallist <= 1 then return end local coin=extendCounterCoin for i=1,#finallist do if string.sub(finallist[i].script_code,finallist[i].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or finallist[i].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then finallist[i].call("extflash",{finallist}) if coin then finallist[i].call("scriptcoin",{coin,invertcoin,coinzero}) end else local guid=finallist[i].getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end end printToAll("Connected ".. #finallist .." counters.") end function watchDesc() if savedDesc != self.getDescription() then local a,b=readDesc() createButtons(a,b) savedDesc=self.getDescription() end if savedTint != self.getColorTint() then local a,b=readDesc() createButtons(a,b) savedTint=self.getColorTint() end Wait.time(watchDesc,0.5) end function updateContextMenu() self.clearContextMenu() self.addContextMenuItem("extend counter",extendc) if extendCounterObjs != nil then self.addContextMenuItem("clear",function() local a,minus,c=getTotalValue(); if coinzero == -1 then minus=true elseif coinzero == 1 then minus=false elseif coinzero == 2 then minus=not minus end setTotalValue({0,minus}) end) end self.addContextMenuItem("make autocalc",autocalc) savechanged=true end function extendc(col) if col == nil then extendCounterObjs=nil return end extendCounterObjs=Player[col].getSelectedObjects() extendCounterCoin=nil if extendCounterObjs != nil then if #extendCounterObjs <= 1 then extendCounterObjs=nil elseif #extendCounterObjs >= 2 then -- if self != extendCounterObjs[1] then -- printToAll("[ff0000]ERROR:[-]select smallest counter first, and from smallest counter right click menu.") -- return -- end if extendCounterObjs[i].type.."" != "Counter" then local i=1 while i <= #extendCounterObjs do if string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) and extendCounterObjs[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then local typetest=extendCounterObjs[i].type.."" == "Counter" or (extendCounterObjs[i].getVar("whatIAm") == "Counter") if i == 2 then if i == #extendCounterObjs then extendCounterCoin=extendCounterObjs[#extendCounterObjs] extendCounterObjs=nil return end elseif i == #extendCounterObjs and not typetest then log("LinkkingCounters:we assume this is coin (negitve display)") extendCounterCoin=extendCounterObjs[#extendCounterObjs] table.remove(extendCounterObjs) elseif typetest then printToAll("[ff0000]ERROR:[-]Unknown counter (possibly unexpected behaviour).") else table.remove(extendCounterObjs,i) i=i-1 end elseif string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) then printToAll("[ff0000]ERROR:[-]Counters not the same version (Advanced Counter Mark II) (possibly unexpected behaviour).") end i=i+1 end if #extendCounterObjs >= 2 then extendCounterObjs[1].call("scriptext",{extendCounterObjs,1}) end for i=1, #extendCounterObjs do if extendCounterObjs[i] != self then extendCounterObjs[i].call("scriptcoin",{extendCounterCoin,invertcoin,coinzero}) end end end end updateContextMenu() end function autocalc(col) savechanged=true autoCalculateList=nil if col == nil then return end autoCalculateList=Player[col].getSelectedObjects() Player[col].clearSelectedObjects() if autoCalculateList == nil then return end local i=1 while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i != #autoCalculateList then local test=isOperator(autoCalculateList[i].getName()) if not test then test=isOperator(autoCalculateList[i].getDescription()) end if not test then printToAll("[ff0000]ERROR:[-]autocalc: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) else local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,0),0.45) end, i*0.3+0.7) end else if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then log("non Advanced Counter Mark II detected (or too old version). "..i) else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then log("other version of Advanced Counter Mark II detected. "..i) else log("[00ff00]OK:[-]same version of Advanced Counter Mark II detected. "..i) end end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) end i=i+1 end log(autoCalculateList) table.remove(autoCalculateList) -- remove self if #autoCalculateList > 1 and ((#autoCalculateList % 2) == 1) then autoCalculateActive=false autocalcOperation() else printToAll("[ff0000]ERROR:[-] ".. #autoCalculateList .." long list failed (dropped). Select odd number of objects, starting from counter, then finally select counter to display the value (paired number of selected objects).") autoCalculateList=nil end end function autocalcOperation() if autoCalculateList != nil then if not autoCalculateActive then autoCalculateActive=true local i=1 local lastop local mycalc,myminus=0,false while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i == #autoCalculateList then printToAll("[ff0000]ERROR:[-]autocalcOperation: last one cannot be operator.") end local test=isOperator(autoCalculateList[i].getName()) if test then lastop=autoCalculateList[i].getName() else test=isOperator(autoCalculateList[i].getDescription()) if test then lastop=autoCalculateList[i].getDescription() else printToAll("[ff0000]ERROR:[-]autocalcOperation: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end end else local var,minus,index if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" and not autoCalculateList[i].getVar("Supports_getTotalValue") then var=autoCalculateList[i].getValue() minus=var < 0 else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) else var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) end end if i == 1 then mycalc=math.abs(var) myminus=minus else mycalc,myminus=rawCalcOperation(lastop,mycalc,var,myminus,minus) end end i=i+1 end setTotalValue({mycalc,myminus}) autoCalculateActive=false autoCalculateWait=Wait.time(autocalcOperation,1.0) end end end function debugme() log(extendCounterObjs) log(extendCounterCoin) if autoCalculateList != nil then for i, obj in ipairs(autoCalculateList) do local guid=obj.getGUID() local times=#autoCalculateList Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 0) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 1) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 2) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 3) end else log("nil") end local a,b=readDesc() log(a) log(b) end function extflash(tab) if tab[1] == nil then for i=1, 7 do Wait.time(function() self.highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end else for i=1, 7 do Wait.time(function() self.highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end extset(tab) end function extset(tab) extendCounterObjs=tab[1] updateContextMenu() end function scriptext(tab) if #tab[1] >= tab[2] then extendCounterObjs=tab[1] if #tab[1] > tab[2] then if string.sub(tab[1][tab[2]+1].script_code,tab[1][tab[2]+1].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or tab[1][tab[2]+1].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then tab[1][tab[2]+1].call("scriptext",{tab[1],tab[2]+1}) else -- end end updateContextMenu() end end function scriptcoin(coin) extendCounterCoin=coin[1] if #coin > 1 then if coin[2] != nil then invertcoin=coin[2] end if #coin > 2 then if coin[3] != nil then coinzero=coin[3] end end end end function createButtons(buttonlist,whatlist) self.clearButtons() local bgcol=self.getColorTint() local test=(bgcol.r * 0.3 + bgcol.r * 0.3 * (1-bgcol.g) + bgcol.g + bgcol.b * 0.4 > 0.925) local txtcol=test and Color(1,1,1) or Color(0,0,0) local buttcol=test and Color(0.2,0.2,0.2) or Color(0.8,0.8,0.8) local butthov=Color(0.5,0.5,0.5) --[[ self.createButton({ click_function=nil, function_owner=self, label=" ", position=Vector(0,0.2,-0.4-(math.ceil(#buttonlist/2)*0.08-0.08)), scale=Vector(0.1,1,0.1), width=4500, height=800*math.ceil(#buttonlist/2)+200, color={bgcol.r,bgcol.g,bgcol.b}, hover_color={bgcol.r,bgcol.g,bgcol.b}, press_color={bgcol.r,bgcol.g,bgcol.b} })]] local buttonorginpos=Vector(0.32,0.201,-0.41) local frame={ click_function="button", function_owner=self, label=" ", font_size=400, position=buttonorginpos, rotation=Vector(0,180,0), scale=Vector(0.1,1,0.1), width=1000, height=600, color={buttcol.r,buttcol.g,buttcol.b}, hover_color={butthov.r,butthov.g,butthov.b}, press_color={butthov.r,butthov.g,butthov.b}, font_color={txtcol.r,txtcol.g,txtcol.b} } local i=1 local slot=0 local line=0 local halfi=0 local function slothand(slot,lablen) if lablen == 1 then if slot == 0 then return 0 elseif slot == 1 then return -0.21 elseif slot == 2 then return -0.43 elseif slot == 3 then return -0.64 end elseif lablen == 2 then if slot == 0 then return -0.105 elseif slot == 1 then return -0.32 elseif slot == 2 then return -0.535 end elseif lablen == 3 then if slot == 0 then return -0.21 elseif slot == 1 then return -0.43 end elseif lablen == 4 then return -0.32 end end while i <= #buttonlist do local lastone=i == #buttonlist local curra,currb local test=whatlist[i] == "" if test then curra,currb=makecopytab(frame,1),makecopytab(frame,1) else curra=makecopytab(frame,1) end local formatted local formtype=numinter(buttonlist[i],nil,true) if formtype == "1" then formatted=string.format("%d",buttonlist[i]) else formatted=buttonlist[i] end local poslab=(test and "+" or (whatlist[i]))..formatted local neglab="-"..formatted local lablen=math.ceil(string.len(poslab)/4.5) if lablen > 4 then lablen=4; end curra.click_function=curra.click_function..(i-1+halfi)*2 if test then currb.click_function=currb.click_function..(i-1+halfi)*2+1 attachIndex("button",(i-1+halfi)*2) attachIndex("button",(i-1+halfi)*2+1) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=neglab if slot+lablen > 4 then line=line+1; slot=0; end currb.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) currb.width=lablen * currb.width currb.label=poslab self.createButton(curra) self.createButton(currb) else attachIndex("button",(i-1+halfi)*2) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=poslab self.createButton(curra) halfi=halfi-0.5 end i=i+1 end end function dummy() end function attachIndex(click_function, index) -- function to create multiple versions of function local fn_name = click_function .. index _G[fn_name] = function(obj, player_color, alt_click) _G[click_function](obj, player_color, alt_click, index) end return fn_name end function getTotalValue() if extendCounterObjs == nil then if extendCounterCoin == nil then local var=tonumber(self.getValue()) or 0 return var,var < 0,1 else local minus local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end return (minus and -math.abs(tonumber(self.getValue()) or 0) or math.abs(tonumber(self.getValue()) or 0)),minus,1 end else local meCounterIndex local i=1 while i <= #extendCounterObjs do if extendCounterObjs[i] == self then meCounterIndex=i end if extendCounterObjs[i] == nil then log("linked counter operation, counter "..i.." removed.") table.remove(extendCounterObjs,i) i=i-1 end i=i+1 end if #extendCounterObjs <= 1 then printToAll("[ff0000]ERROR:[-]Only one counter left, and started linkked counter operation.") extendCounterObjs=nil updateContextMenu() return getTotalValue() end if meCounterIndex == nil then printToAll("[ff0000]ERROR:[-]did not find index of counter."); return nil,nil,nil end local var=0 i=#extendCounterObjs local minus if extendCounterCoin == nil then minus=false else local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end end while i >= 1 do var=math.abs(tonumber(extendCounterObjs[i].getValue()) or 0) + var * 10000 i=i-1 end return (minus and -var or var),minus,meCounterIndex end end function setTotalValue(tab) local var,minus if type(tab).."" == "table" then if #tab >= 1 then var=tab[1] end if #tab >= 2 then minus=tab[2] end else log("setTotalValue:not a table") end if extendCounterObjs == nil then if minus == nil then minus=var < 0 end if minus and extendCounterCoin == nil then var=math.abs(var) % (minus and 1000 or 10000) elseif extendCounterCoin != nil then var=math.abs(var) % 10000 local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end if extendCounterCoin == nil then self.setValue(minus and -var or var) else self.setValue(var) end else if minus == nil then minus=var < 0 end var=var % math.pow(10000,#extendCounterObjs) if minus and extendCounterCoin == nil then var=math.pow(10000,#extendCounterObjs) - var elseif extendCounterCoin != nil then local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end i=#extendCounterObjs while i >= 1 do extendCounterObjs[i].setValue(math.floor(var/math.pow(10000,i-1)) % 10000) i=i-1 end end end function button(obj, col, alt_click, index) local list=self.getButtons() local var,minus,meCounterIndex=getTotalValue() local currlabel=list[index+1].label local oplett=string.sub(currlabel,1,1) local addable=numinter(string.sub(currlabel,2),0) var,minus=rawCalcOperation(oplett,var,addable * math.pow(10000,meCounterIndex-1),minus,false) setTotalValue({var,minus}) end function wrapCalcOperation(tab) local a,b,c,d,e if type(tab).."" == "table" then if #tab >= 1 then a=tab[1] end if #tab >= 2 then b=tab[2] end if #tab >= 3 then c=tab[3] end if #tab >= 4 then d=tab[4] end if #tab >= 5 then e=tab[5] end for name, item in pairs(tab) do if name == "oplett" then a=item elseif name == "var" then b=item elseif name == "addable" then c=item elseif name == "minus" then d=item elseif name == "addmeg" then e=item end end local var,minus=rawCalcOperation(a,b,c,d,e) return var,minus else log("wrapCalcOperation:not a table") return nil,nil end end function rawCalcOperation(oplett,var,addable,minus,addneg) if minus == nil then if var < 0 then minus=true else minus=false end end if addneg == nil then if addable < 0 then addneg=true else addneg=false end end if isOperator(oplett) then -- if oplett == "+" or oplett == "-" then -- if oplett == "-" and minus then -- oplett="+" -- elseif oplett == "+" and minus then -- oplett="-" -- end -- end else log("rawCalcOperation:Wrong operator") end if minus == addneg then local pah if oplett == "-" and minus then oplett = "+" end pah,var=isOperator(oplett,var,addable) else local pah if oplett == "-" then oplett = "+" elseif oplett == "+" then oplett = "-" end if minus then -- addable positive, var negative pah,var=isOperator(oplett,var,addable) else -- addable negative, var positive pah,var=isOperator(oplett,var,addable) end end if coinzero == 0 then if var < 0 then minus=not minus end elseif coinzero == -1 then if var < 0 then minus=not minus elseif 0 == var then minus=true end elseif coinzero == 1 then if var < 0 then minus=not minus elseif 0 == var then minus=false end elseif coinzero == 2 then if var >= 0 then minus=not minus end elseif coinzero == -2 then if var < 0 then minus=not minus end end return math.abs(var),minus end function isOperator(str,a,b) if type(str).."" == "string" then if string.len(str) == 1 then if type(a).."" == "number" and type(b).."" == "number" then a,b=math.abs(a),math.abs(b) if str == "+" then return true,a+b elseif str == "-" then return true,a-b elseif str == "*" then local pa,pb=a%100000000,b%100000000 local ba,bb=(a-pa)/100000000,(b-pb)/100000000 return true,pa*pb + ((ba*pb)%100000000)*100000000 + ((bb*pa)%100000000)*100000000 elseif str == "/" then return true,math.floor(a/b) elseif str == "&" then local ta,tb=a,b local i=0 local num=0 while ta != 0 and tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == cb and ca == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "|" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == 1 or cb == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "^" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if (ca == 1 and cb == 0) or (ca == 0 and cb == 1) then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "%" then return true,a%b elseif str == "<" then if b == 0 then return true,a end return true,a * math.pow(2,b) elseif str == ">" then if b == 0 then return true,a end return true,math.floor(a / math.pow(2,b)) elseif str == "p" then return true,math.floor(math.pow(a,b)) elseif str == "r" then return true,math.floor(math.pow(a,1.0/b)) end else if str == "+" then return true end if str == "-" then return true end if str == "*" then return true end if str == "/" then return true end if str == "&" then return true end if str == "|" then return true end if str == "^" then return true end if str == "%" then return true end if str == "<" then return true end if str == ">" then return true end if str == "p" then return true end if str == "r" then return true end end else log("isOperator:only one mark accepted ("..str..")") end else log("isOperator:only strings (of one character) accepted") end return false end function numinter(num,default,indentify) if type(num).."" == "number" then return num end if type(num).."" == "string" then local check="0123456789abcdefghijklmnopqrstuvwxyz" local out=nil if string.sub(num,1,1) == "0" then --hex or octaconal if string.sub(num,2,2) == "x" then --hex (base 16) if indentify then return "x" end local i=3 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:hex:not regonized character (".. c ..")"); elseif f >= 1 and f <= 16 then out=(out or 0) * 16 + f - 1 else log("numinter:hex:character out of bounds (".. (f-1) .. ")") end i=i+1 end else --octaconal (base 8) if indentify then return "0" end local i=2 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:octa:not regonized character (".. c ..")"); elseif f >= 1 and f <= 8 then out=(out or 0) * 8 + f - 1 else log("numinter:octa:character out of bounds (".. (f-1) .. "),(".. c ..")") end i=i+1 end end else if indentify then return "1" end out=tonumber(num) end if out == nil then return default else return out end end return default end function readDesc() local buttonlist={} local whatlist={} local desc=self.getDescription() or "" local txtstep=string.find(desc,",",1,true) if txtstep != nil then local prevstep repeat local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),txtstep-1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end prevstep=txtstep txtstep=string.find(desc,",",txtstep+1,true) until txtstep == nil or txtstep == string.len(desc) if textstep == nil then local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),string.len(desc)) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end elseif string.len(desc) > 0 then local poper=string.sub(desc,1,1) local test=isOperator(poper) local num=string.sub(desc,test and 2 or 1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end return buttonlist,whatlist end function makecopytab(tab,depth) local mydepth=depth or 0 if mydepth < 0 then log("this should not have been called. makecopytab") log(tab) return nil end local newtab={} if type(tab).."" == "table" then for x, val in pairs(tab) do if type(x).."" == "number" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then table.insert(newtab,x,Vector(tab[x])) else if mydepth > 0 then table.insert(newtab,x,makecopytab(tab[x],mydepth-1)) else table.insert(newtab,x,{}) end end else table.insert(newtab,x,tab[x]) end elseif type(x).."" == "string" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then newtab[x]=Vector(tab[x]) else if mydepth > 0 then newtab[x]=makecopytab(tab[x],mydepth-1) else newtab[x]={} end end else newtab[x]=tab[x] end end end else return tab end return newtab end function vectorRotate(vec,rot) return vec:rotateOver("z",rot.z):rotateOver("x",rot.x):rotateOver("y",rot.y) end function vectorIRotate(vec,rot) return vec:rotateOver("y",rot.y):rotateOver("x",rot.x):rotateOver("z",rot.z) end function vectorToLocal(target,objvec,objscale,objrot) local copy=Vector(target) copy=copy-(objvec or Vector(0,0,0)) copy=vectorIRotate(copy,(objrot or Vector(0,0,0)):inverse()) local tmp=objscale or Vector(1,1,1) copy=Vector(copy.x / tmp.x,copy.y / tmp.y, copy.z / tmp.z) return copy end function wrapVectorToLocal(tab) return vectorToLocal(tab[1],tab[2],tab[3],tab[4]) end function findInRadiusBy(pos, radius, func, debug) --by MrStump https://steamcommunity.com/sharedfiles/filedetails/?id=752690530&searchtext=lua --if DEBUG then log(" findInRadiusBy(): just called") end local radius = (radius or 1) local objList = Physics.cast({ origin=pos, direction={0,1,0}, type=2, size={radius,radius,radius}, max_distance=0, debug=(debug or false) }) local refinedList = {} for _, obj in ipairs(objList) do if func == nil then if obj.hit_object.type != "Surface" then -- Finaryman Mod table.insert(refinedList, obj.hit_object) end else if func(obj.hit_object) and obj.hit_object.type != "Surface" then --Finaryman Mod table.insert(refinedList, obj.hit_object) end end end return refinedList endLuaScriptState[]XmlUI190Ó¥GUID263d1bNameCounterTransform‰posX€A@posY\ºí?posZ@rotX ç)“¾rotY@æ@T¿rotZÀTý„¾scaleX€ÿÿû?scaleY€ÿÿû?scaleZ€ÿÿû?NicknameMoneyDescription 2,5,10,25GMNotesAltLookAngle&xyzColorDiffuse&r <5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCountervalueLuaScriptq£function onLoad(str) --In code settings-- invertcoin=false --old negative value is now positive and old positive value is now negative coinzero=-2 --0 > toggle when beond zero, -1 > zero is negative, 1 > zero is positive, 2 > toggle when reached zero, -2 > zero is special autoconnect=true --allow autoconnecting by putting counters next to each other howfaraconn=0.6 --how far autoconnect works (object scale affects this) showcalcround=true --show autocalculation list on hover --End of settings--- savechanged=false local start=false SETTINGS_POS=string.find(self.script_code,"--End of settings---") self.setVar("SETTINGS_POS",SETTINGS_POS) if str != "" and str != nil then local data=JSON.decode(str) for name, info in pairs(data) do if name == "extendCounterObjs" then if type(info).."" == "table" then if #info > 1 then extendCounterObjs={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(extendCounterObjs,obj) end end if #extendCounterObjs < 2 then extendCounterObjs=nil end end end end if name == "extendCounterCoin" then local obj=getObjectFromGUID(info) if obj then extendCounterCoin=obj end end if name == "autoCalculateList" then if type(info).."" == "table" then if #info > 2 then autoCalculateList={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(autoCalculateList,obj) end end if #autoCalculateList < 3 then autoCalculateList=nil else start=true end end end end end end self.setVar("whatIAm","Counter") self.setVar("Supports_getTotalValue",true) self.setVar("whatIAmSpecfically","[finmod]Advanced Counter Mark II") watchDesc() updateContextMenu() if start then autoCalculateActive=false; autocalcOperation(); end end function onSave() local objs={} local autol={} local rettab={} local coin if savechanged then if extendCounterCoin then coin=extendCounterCoin.getGUID() end if type(extendCounterObjs).."" == "table" then for _, obj in ipairs(extendCounterObjs) do if obj then table.insert(objs,obj.getGUID()) end end end if type(autoCalculateList).."" == "table" then for _, obj in ipairs(autoCalculateList) do if obj then table.insert(autol,obj.getGUID()) end end end if #objs > 1 then rettab["extendCounterObjs"]=objs end if coin then rettab["extendCounterCoin"]=coin end if #autol > 2 then rettab["autoCalculateList"]=autol end savechanged=false return JSON.encode(rettab) else return self.script_state end end function getAnyVar(tab) return _G[tab[1]] end function setAnyVar(tab) _G[tab[1]]=tab[2] end function onHover(col) if autoCalculateList != nil and showcalcround then local showme={ color=Color(1,1,1), thickness=0.1, rotation=Vector(0,0,0), points={} } local pos=self.getPosition()+Vector(0,0.5,0) local ipos=self.getPosition()-Vector(0,1.5,0) local prevvec=vectorToLocal(pos,self.getPosition(),self.getScale(),self.getRotation()) local list={} i=#autoCalculateList while i > 0 do showme.color=Color(1,1,1):lerp(Color(0,0,1),(#autoCalculateList-i)/(#autoCalculateList-1)) table.insert(list,makecopytab(showme,1)) list[#autoCalculateList-i+1].points[1]=prevvec local obj=autoCalculateList[i] list[#autoCalculateList-i+1].points[2]=vectorToLocal(obj.getPosition(),ipos,self.getScale()*Vector(3,3,3),self.getRotation()) prevvec=list[#autoCalculateList-i+1].points[2] i=i-1 end self.setVectorLines(list) Wait.time(function() self.setVectorLines() end, 3.0) end end function onPickUp(color) if type(extendCounterObjs).."" == "table" then local amount=#extendCounterObjs local selob=Player[color].getSelectedObjects() if selob then if #selob == amount then for i=1, amount do local test = false for x=1, amount do if selob[i] == extendCounterObjs[x] then test=true end end if test then return end end end end for i, obj in ipairs(extendCounterObjs) do if obj then if string.sub(obj.script_code,obj.getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or obj.getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then obj.call("extflash",{nil}) obj.call("updateContextMenu") else local guid=obj.getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end end end end printToAll("broke connection of ".. amount .." counters.") end end function onDrop(color) startChecking() end function startChecking() if autoconnect then preCheck(os.time()+3) end end function preCheck(secs) if os.time() < secs then if not self.resting and checkWait == nil then checkWait=Wait.time(function() preCheck(secs) end,0.1) else checkWait=nil checkConnections() end else checkWait=nil end end function checkConnections() local finallist={self} local bd=self.getBounds() local scale=self.getScale() local x=bd.size.x / 2.0 local rot=self.getRotation() local left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) local right=Vector()-left local cpos=self.getPosition() local tmppos=cpos local test=true while test do local list=findInRadiusBy(tmppos+left,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,list[1]) else test=false end end tmppos=cpos test=true while test do local list=findInRadiusBy(tmppos+right,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 right=Vector(x+(howfaraconn+0.5)*scale.x,-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,1,list[1]) else test=false end end if #finallist <= 1 then return end local coin=extendCounterCoin for i=1,#finallist do if string.sub(finallist[i].script_code,finallist[i].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or finallist[i].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then finallist[i].call("extflash",{finallist}) if coin then finallist[i].call("scriptcoin",{coin,invertcoin,coinzero}) end else local guid=finallist[i].getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end end printToAll("Connected ".. #finallist .." counters.") end function watchDesc() if savedDesc != self.getDescription() then local a,b=readDesc() createButtons(a,b) savedDesc=self.getDescription() end if savedTint != self.getColorTint() then local a,b=readDesc() createButtons(a,b) savedTint=self.getColorTint() end Wait.time(watchDesc,0.5) end function updateContextMenu() self.clearContextMenu() self.addContextMenuItem("extend counter",extendc) if extendCounterObjs != nil then self.addContextMenuItem("clear",function() local a,minus,c=getTotalValue(); if coinzero == -1 then minus=true elseif coinzero == 1 then minus=false elseif coinzero == 2 then minus=not minus end setTotalValue({0,minus}) end) end self.addContextMenuItem("make autocalc",autocalc) savechanged=true end function extendc(col) if col == nil then extendCounterObjs=nil return end extendCounterObjs=Player[col].getSelectedObjects() extendCounterCoin=nil if extendCounterObjs != nil then if #extendCounterObjs <= 1 then extendCounterObjs=nil elseif #extendCounterObjs >= 2 then -- if self != extendCounterObjs[1] then -- printToAll("[ff0000]ERROR:[-]select smallest counter first, and from smallest counter right click menu.") -- return -- end if extendCounterObjs[i].type.."" != "Counter" then local i=1 while i <= #extendCounterObjs do if string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) and extendCounterObjs[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then local typetest=extendCounterObjs[i].type.."" == "Counter" or (extendCounterObjs[i].getVar("whatIAm") == "Counter") if i == 2 then if i == #extendCounterObjs then extendCounterCoin=extendCounterObjs[#extendCounterObjs] extendCounterObjs=nil return end elseif i == #extendCounterObjs and not typetest then log("LinkkingCounters:we assume this is coin (negitve display)") extendCounterCoin=extendCounterObjs[#extendCounterObjs] table.remove(extendCounterObjs) elseif typetest then printToAll("[ff0000]ERROR:[-]Unknown counter (possibly unexpected behaviour).") else table.remove(extendCounterObjs,i) i=i-1 end elseif string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) then printToAll("[ff0000]ERROR:[-]Counters not the same version (Advanced Counter Mark II) (possibly unexpected behaviour).") end i=i+1 end if #extendCounterObjs >= 2 then extendCounterObjs[1].call("scriptext",{extendCounterObjs,1}) end for i=1, #extendCounterObjs do if extendCounterObjs[i] != self then extendCounterObjs[i].call("scriptcoin",{extendCounterCoin,invertcoin,coinzero}) end end end end updateContextMenu() end function autocalc(col) savechanged=true autoCalculateList=nil if col == nil then return end autoCalculateList=Player[col].getSelectedObjects() Player[col].clearSelectedObjects() if autoCalculateList == nil then return end local i=1 while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i != #autoCalculateList then local test=isOperator(autoCalculateList[i].getName()) if not test then test=isOperator(autoCalculateList[i].getDescription()) end if not test then printToAll("[ff0000]ERROR:[-]autocalc: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) else local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,0),0.45) end, i*0.3+0.7) end else if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then log("non Advanced Counter Mark II detected (or too old version). "..i) else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then log("other version of Advanced Counter Mark II detected. "..i) else log("[00ff00]OK:[-]same version of Advanced Counter Mark II detected. "..i) end end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) end i=i+1 end log(autoCalculateList) table.remove(autoCalculateList) -- remove self if #autoCalculateList > 1 and ((#autoCalculateList % 2) == 1) then autoCalculateActive=false autocalcOperation() else printToAll("[ff0000]ERROR:[-] ".. #autoCalculateList .." long list failed (dropped). Select odd number of objects, starting from counter, then finally select counter to display the value (paired number of selected objects).") autoCalculateList=nil end end function autocalcOperation() if autoCalculateList != nil then if not autoCalculateActive then autoCalculateActive=true local i=1 local lastop local mycalc,myminus=0,false while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i == #autoCalculateList then printToAll("[ff0000]ERROR:[-]autocalcOperation: last one cannot be operator.") end local test=isOperator(autoCalculateList[i].getName()) if test then lastop=autoCalculateList[i].getName() else test=isOperator(autoCalculateList[i].getDescription()) if test then lastop=autoCalculateList[i].getDescription() else printToAll("[ff0000]ERROR:[-]autocalcOperation: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end end else local var,minus,index if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" and not autoCalculateList[i].getVar("Supports_getTotalValue") then var=autoCalculateList[i].getValue() minus=var < 0 else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) else var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) end end if i == 1 then mycalc=math.abs(var) myminus=minus else mycalc,myminus=rawCalcOperation(lastop,mycalc,var,myminus,minus) end end i=i+1 end setTotalValue({mycalc,myminus}) autoCalculateActive=false autoCalculateWait=Wait.time(autocalcOperation,1.0) end end end function debugme() log(extendCounterObjs) log(extendCounterCoin) if autoCalculateList != nil then for i, obj in ipairs(autoCalculateList) do local guid=obj.getGUID() local times=#autoCalculateList Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 0) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 1) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 2) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 3) end else log("nil") end local a,b=readDesc() log(a) log(b) end function extflash(tab) if tab[1] == nil then for i=1, 7 do Wait.time(function() self.highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end else for i=1, 7 do Wait.time(function() self.highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end extset(tab) end function extset(tab) extendCounterObjs=tab[1] updateContextMenu() end function scriptext(tab) if #tab[1] >= tab[2] then extendCounterObjs=tab[1] if #tab[1] > tab[2] then if string.sub(tab[1][tab[2]+1].script_code,tab[1][tab[2]+1].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or tab[1][tab[2]+1].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then tab[1][tab[2]+1].call("scriptext",{tab[1],tab[2]+1}) else -- end end updateContextMenu() end end function scriptcoin(coin) extendCounterCoin=coin[1] if #coin > 1 then if coin[2] != nil then invertcoin=coin[2] end if #coin > 2 then if coin[3] != nil then coinzero=coin[3] end end end end function createButtons(buttonlist,whatlist) self.clearButtons() local bgcol=self.getColorTint() local test=(bgcol.r * 0.3 + bgcol.r * 0.3 * (1-bgcol.g) + bgcol.g + bgcol.b * 0.4 > 0.925) local txtcol=test and Color(1,1,1) or Color(0,0,0) local buttcol=test and Color(0.2,0.2,0.2) or Color(0.8,0.8,0.8) local butthov=Color(0.5,0.5,0.5) --[[ self.createButton({ click_function=nil, function_owner=self, label=" ", position=Vector(0,0.2,-0.4-(math.ceil(#buttonlist/2)*0.08-0.08)), scale=Vector(0.1,1,0.1), width=4500, height=800*math.ceil(#buttonlist/2)+200, color={bgcol.r,bgcol.g,bgcol.b}, hover_color={bgcol.r,bgcol.g,bgcol.b}, press_color={bgcol.r,bgcol.g,bgcol.b} })]] local buttonorginpos=Vector(0.32,0.201,-0.41) local frame={ click_function="button", function_owner=self, label=" ", font_size=400, position=buttonorginpos, rotation=Vector(0,180,0), scale=Vector(0.1,1,0.1), width=1000, height=600, color={buttcol.r,buttcol.g,buttcol.b}, hover_color={butthov.r,butthov.g,butthov.b}, press_color={butthov.r,butthov.g,butthov.b}, font_color={txtcol.r,txtcol.g,txtcol.b} } local i=1 local slot=0 local line=0 local halfi=0 local function slothand(slot,lablen) if lablen == 1 then if slot == 0 then return 0 elseif slot == 1 then return -0.21 elseif slot == 2 then return -0.43 elseif slot == 3 then return -0.64 end elseif lablen == 2 then if slot == 0 then return -0.105 elseif slot == 1 then return -0.32 elseif slot == 2 then return -0.535 end elseif lablen == 3 then if slot == 0 then return -0.21 elseif slot == 1 then return -0.43 end elseif lablen == 4 then return -0.32 end end while i <= #buttonlist do local lastone=i == #buttonlist local curra,currb local test=whatlist[i] == "" if test then curra,currb=makecopytab(frame,1),makecopytab(frame,1) else curra=makecopytab(frame,1) end local formatted local formtype=numinter(buttonlist[i],nil,true) if formtype == "1" then formatted=string.format("%d",buttonlist[i]) else formatted=buttonlist[i] end local poslab=(test and "+" or (whatlist[i]))..formatted local neglab="-"..formatted local lablen=math.ceil(string.len(poslab)/4.5) if lablen > 4 then lablen=4; end curra.click_function=curra.click_function..(i-1+halfi)*2 if test then currb.click_function=currb.click_function..(i-1+halfi)*2+1 attachIndex("button",(i-1+halfi)*2) attachIndex("button",(i-1+halfi)*2+1) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=neglab if slot+lablen > 4 then line=line+1; slot=0; end currb.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) currb.width=lablen * currb.width currb.label=poslab self.createButton(curra) self.createButton(currb) else attachIndex("button",(i-1+halfi)*2) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=poslab self.createButton(curra) halfi=halfi-0.5 end i=i+1 end end function dummy() end function attachIndex(click_function, index) -- function to create multiple versions of function local fn_name = click_function .. index _G[fn_name] = function(obj, player_color, alt_click) _G[click_function](obj, player_color, alt_click, index) end return fn_name end function getTotalValue() if extendCounterObjs == nil then if extendCounterCoin == nil then local var=tonumber(self.getValue()) or 0 return var,var < 0,1 else local minus local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end return (minus and -math.abs(tonumber(self.getValue()) or 0) or math.abs(tonumber(self.getValue()) or 0)),minus,1 end else local meCounterIndex local i=1 while i <= #extendCounterObjs do if extendCounterObjs[i] == self then meCounterIndex=i end if extendCounterObjs[i] == nil then log("linked counter operation, counter "..i.." removed.") table.remove(extendCounterObjs,i) i=i-1 end i=i+1 end if #extendCounterObjs <= 1 then printToAll("[ff0000]ERROR:[-]Only one counter left, and started linkked counter operation.") extendCounterObjs=nil updateContextMenu() return getTotalValue() end if meCounterIndex == nil then printToAll("[ff0000]ERROR:[-]did not find index of counter."); return nil,nil,nil end local var=0 i=#extendCounterObjs local minus if extendCounterCoin == nil then minus=false else local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end end while i >= 1 do var=math.abs(tonumber(extendCounterObjs[i].getValue()) or 0) + var * 10000 i=i-1 end return (minus and -var or var),minus,meCounterIndex end end function setTotalValue(tab) local var,minus if type(tab).."" == "table" then if #tab >= 1 then var=tab[1] end if #tab >= 2 then minus=tab[2] end else log("setTotalValue:not a table") end if extendCounterObjs == nil then if minus == nil then minus=var < 0 end if minus and extendCounterCoin == nil then var=math.abs(var) % (minus and 1000 or 10000) elseif extendCounterCoin != nil then var=math.abs(var) % 10000 local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end if extendCounterCoin == nil then self.setValue(minus and -var or var) else self.setValue(var) end else if minus == nil then minus=var < 0 end var=var % math.pow(10000,#extendCounterObjs) if minus and extendCounterCoin == nil then var=math.pow(10000,#extendCounterObjs) - var elseif extendCounterCoin != nil then local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end i=#extendCounterObjs while i >= 1 do extendCounterObjs[i].setValue(math.floor(var/math.pow(10000,i-1)) % 10000) i=i-1 end end end function button(obj, col, alt_click, index) local list=self.getButtons() local var,minus,meCounterIndex=getTotalValue() local currlabel=list[index+1].label local oplett=string.sub(currlabel,1,1) local addable=numinter(string.sub(currlabel,2),0) var,minus=rawCalcOperation(oplett,var,addable * math.pow(10000,meCounterIndex-1),minus,false) setTotalValue({var,minus}) end function wrapCalcOperation(tab) local a,b,c,d,e if type(tab).."" == "table" then if #tab >= 1 then a=tab[1] end if #tab >= 2 then b=tab[2] end if #tab >= 3 then c=tab[3] end if #tab >= 4 then d=tab[4] end if #tab >= 5 then e=tab[5] end for name, item in pairs(tab) do if name == "oplett" then a=item elseif name == "var" then b=item elseif name == "addable" then c=item elseif name == "minus" then d=item elseif name == "addmeg" then e=item end end local var,minus=rawCalcOperation(a,b,c,d,e) return var,minus else log("wrapCalcOperation:not a table") return nil,nil end end function rawCalcOperation(oplett,var,addable,minus,addneg) if minus == nil then if var < 0 then minus=true else minus=false end end if addneg == nil then if addable < 0 then addneg=true else addneg=false end end if isOperator(oplett) then -- if oplett == "+" or oplett == "-" then -- if oplett == "-" and minus then -- oplett="+" -- elseif oplett == "+" and minus then -- oplett="-" -- end -- end else log("rawCalcOperation:Wrong operator") end if minus == addneg then local pah if oplett == "-" and minus then oplett = "+" end pah,var=isOperator(oplett,var,addable) else local pah if oplett == "-" then oplett = "+" elseif oplett == "+" then oplett = "-" end if minus then -- addable positive, var negative pah,var=isOperator(oplett,var,addable) else -- addable negative, var positive pah,var=isOperator(oplett,var,addable) end end if coinzero == 0 then if var < 0 then minus=not minus end elseif coinzero == -1 then if var < 0 then minus=not minus elseif 0 == var then minus=true end elseif coinzero == 1 then if var < 0 then minus=not minus elseif 0 == var then minus=false end elseif coinzero == 2 then if var >= 0 then minus=not minus end elseif coinzero == -2 then if var < 0 then minus=not minus end end return math.abs(var),minus end function isOperator(str,a,b) if type(str).."" == "string" then if string.len(str) == 1 then if type(a).."" == "number" and type(b).."" == "number" then a,b=math.abs(a),math.abs(b) if str == "+" then return true,a+b elseif str == "-" then return true,a-b elseif str == "*" then local pa,pb=a%100000000,b%100000000 local ba,bb=(a-pa)/100000000,(b-pb)/100000000 return true,pa*pb + ((ba*pb)%100000000)*100000000 + ((bb*pa)%100000000)*100000000 elseif str == "/" then return true,math.floor(a/b) elseif str == "&" then local ta,tb=a,b local i=0 local num=0 while ta != 0 and tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == cb and ca == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "|" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == 1 or cb == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "^" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if (ca == 1 and cb == 0) or (ca == 0 and cb == 1) then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "%" then return true,a%b elseif str == "<" then if b == 0 then return true,a end return true,a * math.pow(2,b) elseif str == ">" then if b == 0 then return true,a end return true,math.floor(a / math.pow(2,b)) elseif str == "p" then return true,math.floor(math.pow(a,b)) elseif str == "r" then return true,math.floor(math.pow(a,1.0/b)) end else if str == "+" then return true end if str == "-" then return true end if str == "*" then return true end if str == "/" then return true end if str == "&" then return true end if str == "|" then return true end if str == "^" then return true end if str == "%" then return true end if str == "<" then return true end if str == ">" then return true end if str == "p" then return true end if str == "r" then return true end end else log("isOperator:only one mark accepted ("..str..")") end else log("isOperator:only strings (of one character) accepted") end return false end function numinter(num,default,indentify) if type(num).."" == "number" then return num end if type(num).."" == "string" then local check="0123456789abcdefghijklmnopqrstuvwxyz" local out=nil if string.sub(num,1,1) == "0" then --hex or octaconal if string.sub(num,2,2) == "x" then --hex (base 16) if indentify then return "x" end local i=3 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:hex:not regonized character (".. c ..")"); elseif f >= 1 and f <= 16 then out=(out or 0) * 16 + f - 1 else log("numinter:hex:character out of bounds (".. (f-1) .. ")") end i=i+1 end else --octaconal (base 8) if indentify then return "0" end local i=2 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:octa:not regonized character (".. c ..")"); elseif f >= 1 and f <= 8 then out=(out or 0) * 8 + f - 1 else log("numinter:octa:character out of bounds (".. (f-1) .. "),(".. c ..")") end i=i+1 end end else if indentify then return "1" end out=tonumber(num) end if out == nil then return default else return out end end return default end function readDesc() local buttonlist={} local whatlist={} local desc=self.getDescription() or "" local txtstep=string.find(desc,",",1,true) if txtstep != nil then local prevstep repeat local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),txtstep-1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end prevstep=txtstep txtstep=string.find(desc,",",txtstep+1,true) until txtstep == nil or txtstep == string.len(desc) if textstep == nil then local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),string.len(desc)) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end elseif string.len(desc) > 0 then local poper=string.sub(desc,1,1) local test=isOperator(poper) local num=string.sub(desc,test and 2 or 1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end return buttonlist,whatlist end function makecopytab(tab,depth) local mydepth=depth or 0 if mydepth < 0 then log("this should not have been called. makecopytab") log(tab) return nil end local newtab={} if type(tab).."" == "table" then for x, val in pairs(tab) do if type(x).."" == "number" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then table.insert(newtab,x,Vector(tab[x])) else if mydepth > 0 then table.insert(newtab,x,makecopytab(tab[x],mydepth-1)) else table.insert(newtab,x,{}) end end else table.insert(newtab,x,tab[x]) end elseif type(x).."" == "string" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then newtab[x]=Vector(tab[x]) else if mydepth > 0 then newtab[x]=makecopytab(tab[x],mydepth-1) else newtab[x]={} end end else newtab[x]=tab[x] end end end else return tab end return newtab end function vectorRotate(vec,rot) return vec:rotateOver("z",rot.z):rotateOver("x",rot.x):rotateOver("y",rot.y) end function vectorIRotate(vec,rot) return vec:rotateOver("y",rot.y):rotateOver("x",rot.x):rotateOver("z",rot.z) end function vectorToLocal(target,objvec,objscale,objrot) local copy=Vector(target) copy=copy-(objvec or Vector(0,0,0)) copy=vectorIRotate(copy,(objrot or Vector(0,0,0)):inverse()) local tmp=objscale or Vector(1,1,1) copy=Vector(copy.x / tmp.x,copy.y / tmp.y, copy.z / tmp.z) return copy end function wrapVectorToLocal(tab) return vectorToLocal(tab[1],tab[2],tab[3],tab[4]) end function findInRadiusBy(pos, radius, func, debug) --by MrStump https://steamcommunity.com/sharedfiles/filedetails/?id=752690530&searchtext=lua --if DEBUG then log(" findInRadiusBy(): just called") end local radius = (radius or 1) local objList = Physics.cast({ origin=pos, direction={0,1,0}, type=2, size={radius,radius,radius}, max_distance=0, debug=(debug or false) }) local refinedList = {} for _, obj in ipairs(objList) do if func == nil then if obj.hit_object.type != "Surface" then -- Finaryman Mod table.insert(refinedList, obj.hit_object) end else if func(obj.hit_object) and obj.hit_object.type != "Surface" then --Finaryman Mod table.insert(refinedList, obj.hit_object) end end end return refinedList endLuaScriptState[]XmlUI191Ó¥GUID3171d7NameCounterTransform‰posX€A@posY@\ºí?posZ6@rotXÀIþ¶>rotY@å@T¿rotZÀjD‚¾scaleX€ÿÿû?scaleY€ÿÿû?scaleZ€ÿÿû?NicknameMoneyDescription 2,5,10,25GMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g –™¹?b`^¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCountervalueLuaScriptq£function onLoad(str) --In code settings-- invertcoin=false --old negative value is now positive and old positive value is now negative coinzero=-2 --0 > toggle when beond zero, -1 > zero is negative, 1 > zero is positive, 2 > toggle when reached zero, -2 > zero is special autoconnect=true --allow autoconnecting by putting counters next to each other howfaraconn=0.6 --how far autoconnect works (object scale affects this) showcalcround=true --show autocalculation list on hover --End of settings--- savechanged=false local start=false SETTINGS_POS=string.find(self.script_code,"--End of settings---") self.setVar("SETTINGS_POS",SETTINGS_POS) if str != "" and str != nil then local data=JSON.decode(str) for name, info in pairs(data) do if name == "extendCounterObjs" then if type(info).."" == "table" then if #info > 1 then extendCounterObjs={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(extendCounterObjs,obj) end end if #extendCounterObjs < 2 then extendCounterObjs=nil end end end end if name == "extendCounterCoin" then local obj=getObjectFromGUID(info) if obj then extendCounterCoin=obj end end if name == "autoCalculateList" then if type(info).."" == "table" then if #info > 2 then autoCalculateList={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(autoCalculateList,obj) end end if #autoCalculateList < 3 then autoCalculateList=nil else start=true end end end end end end self.setVar("whatIAm","Counter") self.setVar("Supports_getTotalValue",true) self.setVar("whatIAmSpecfically","[finmod]Advanced Counter Mark II") watchDesc() updateContextMenu() if start then autoCalculateActive=false; autocalcOperation(); end end function onSave() local objs={} local autol={} local rettab={} local coin if savechanged then if extendCounterCoin then coin=extendCounterCoin.getGUID() end if type(extendCounterObjs).."" == "table" then for _, obj in ipairs(extendCounterObjs) do if obj then table.insert(objs,obj.getGUID()) end end end if type(autoCalculateList).."" == "table" then for _, obj in ipairs(autoCalculateList) do if obj then table.insert(autol,obj.getGUID()) end end end if #objs > 1 then rettab["extendCounterObjs"]=objs end if coin then rettab["extendCounterCoin"]=coin end if #autol > 2 then rettab["autoCalculateList"]=autol end savechanged=false return JSON.encode(rettab) else return self.script_state end end function getAnyVar(tab) return _G[tab[1]] end function setAnyVar(tab) _G[tab[1]]=tab[2] end function onHover(col) if autoCalculateList != nil and showcalcround then local showme={ color=Color(1,1,1), thickness=0.1, rotation=Vector(0,0,0), points={} } local pos=self.getPosition()+Vector(0,0.5,0) local ipos=self.getPosition()-Vector(0,1.5,0) local prevvec=vectorToLocal(pos,self.getPosition(),self.getScale(),self.getRotation()) local list={} i=#autoCalculateList while i > 0 do showme.color=Color(1,1,1):lerp(Color(0,0,1),(#autoCalculateList-i)/(#autoCalculateList-1)) table.insert(list,makecopytab(showme,1)) list[#autoCalculateList-i+1].points[1]=prevvec local obj=autoCalculateList[i] list[#autoCalculateList-i+1].points[2]=vectorToLocal(obj.getPosition(),ipos,self.getScale()*Vector(3,3,3),self.getRotation()) prevvec=list[#autoCalculateList-i+1].points[2] i=i-1 end self.setVectorLines(list) Wait.time(function() self.setVectorLines() end, 3.0) end end function onPickUp(color) if type(extendCounterObjs).."" == "table" then local amount=#extendCounterObjs local selob=Player[color].getSelectedObjects() if selob then if #selob == amount then for i=1, amount do local test = false for x=1, amount do if selob[i] == extendCounterObjs[x] then test=true end end if test then return end end end end for i, obj in ipairs(extendCounterObjs) do if obj then if string.sub(obj.script_code,obj.getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or obj.getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then obj.call("extflash",{nil}) obj.call("updateContextMenu") else local guid=obj.getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end end end end printToAll("broke connection of ".. amount .." counters.") end end function onDrop(color) startChecking() end function startChecking() if autoconnect then preCheck(os.time()+3) end end function preCheck(secs) if os.time() < secs then if not self.resting and checkWait == nil then checkWait=Wait.time(function() preCheck(secs) end,0.1) else checkWait=nil checkConnections() end else checkWait=nil end end function checkConnections() local finallist={self} local bd=self.getBounds() local scale=self.getScale() local x=bd.size.x / 2.0 local rot=self.getRotation() local left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) local right=Vector()-left local cpos=self.getPosition() local tmppos=cpos local test=true while test do local list=findInRadiusBy(tmppos+left,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,list[1]) else test=false end end tmppos=cpos test=true while test do local list=findInRadiusBy(tmppos+right,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 right=Vector(x+(howfaraconn+0.5)*scale.x,-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,1,list[1]) else test=false end end if #finallist <= 1 then return end local coin=extendCounterCoin for i=1,#finallist do if string.sub(finallist[i].script_code,finallist[i].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or finallist[i].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then finallist[i].call("extflash",{finallist}) if coin then finallist[i].call("scriptcoin",{coin,invertcoin,coinzero}) end else local guid=finallist[i].getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end end printToAll("Connected ".. #finallist .." counters.") end function watchDesc() if savedDesc != self.getDescription() then local a,b=readDesc() createButtons(a,b) savedDesc=self.getDescription() end if savedTint != self.getColorTint() then local a,b=readDesc() createButtons(a,b) savedTint=self.getColorTint() end Wait.time(watchDesc,0.5) end function updateContextMenu() self.clearContextMenu() self.addContextMenuItem("extend counter",extendc) if extendCounterObjs != nil then self.addContextMenuItem("clear",function() local a,minus,c=getTotalValue(); if coinzero == -1 then minus=true elseif coinzero == 1 then minus=false elseif coinzero == 2 then minus=not minus end setTotalValue({0,minus}) end) end self.addContextMenuItem("make autocalc",autocalc) savechanged=true end function extendc(col) if col == nil then extendCounterObjs=nil return end extendCounterObjs=Player[col].getSelectedObjects() extendCounterCoin=nil if extendCounterObjs != nil then if #extendCounterObjs <= 1 then extendCounterObjs=nil elseif #extendCounterObjs >= 2 then -- if self != extendCounterObjs[1] then -- printToAll("[ff0000]ERROR:[-]select smallest counter first, and from smallest counter right click menu.") -- return -- end if extendCounterObjs[i].type.."" != "Counter" then local i=1 while i <= #extendCounterObjs do if string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) and extendCounterObjs[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then local typetest=extendCounterObjs[i].type.."" == "Counter" or (extendCounterObjs[i].getVar("whatIAm") == "Counter") if i == 2 then if i == #extendCounterObjs then extendCounterCoin=extendCounterObjs[#extendCounterObjs] extendCounterObjs=nil return end elseif i == #extendCounterObjs and not typetest then log("LinkkingCounters:we assume this is coin (negitve display)") extendCounterCoin=extendCounterObjs[#extendCounterObjs] table.remove(extendCounterObjs) elseif typetest then printToAll("[ff0000]ERROR:[-]Unknown counter (possibly unexpected behaviour).") else table.remove(extendCounterObjs,i) i=i-1 end elseif string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) then printToAll("[ff0000]ERROR:[-]Counters not the same version (Advanced Counter Mark II) (possibly unexpected behaviour).") end i=i+1 end if #extendCounterObjs >= 2 then extendCounterObjs[1].call("scriptext",{extendCounterObjs,1}) end for i=1, #extendCounterObjs do if extendCounterObjs[i] != self then extendCounterObjs[i].call("scriptcoin",{extendCounterCoin,invertcoin,coinzero}) end end end end updateContextMenu() end function autocalc(col) savechanged=true autoCalculateList=nil if col == nil then return end autoCalculateList=Player[col].getSelectedObjects() Player[col].clearSelectedObjects() if autoCalculateList == nil then return end local i=1 while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i != #autoCalculateList then local test=isOperator(autoCalculateList[i].getName()) if not test then test=isOperator(autoCalculateList[i].getDescription()) end if not test then printToAll("[ff0000]ERROR:[-]autocalc: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) else local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,0),0.45) end, i*0.3+0.7) end else if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then log("non Advanced Counter Mark II detected (or too old version). "..i) else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then log("other version of Advanced Counter Mark II detected. "..i) else log("[00ff00]OK:[-]same version of Advanced Counter Mark II detected. "..i) end end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) end i=i+1 end log(autoCalculateList) table.remove(autoCalculateList) -- remove self if #autoCalculateList > 1 and ((#autoCalculateList % 2) == 1) then autoCalculateActive=false autocalcOperation() else printToAll("[ff0000]ERROR:[-] ".. #autoCalculateList .." long list failed (dropped). Select odd number of objects, starting from counter, then finally select counter to display the value (paired number of selected objects).") autoCalculateList=nil end end function autocalcOperation() if autoCalculateList != nil then if not autoCalculateActive then autoCalculateActive=true local i=1 local lastop local mycalc,myminus=0,false while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i == #autoCalculateList then printToAll("[ff0000]ERROR:[-]autocalcOperation: last one cannot be operator.") end local test=isOperator(autoCalculateList[i].getName()) if test then lastop=autoCalculateList[i].getName() else test=isOperator(autoCalculateList[i].getDescription()) if test then lastop=autoCalculateList[i].getDescription() else printToAll("[ff0000]ERROR:[-]autocalcOperation: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end end else local var,minus,index if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" and not autoCalculateList[i].getVar("Supports_getTotalValue") then var=autoCalculateList[i].getValue() minus=var < 0 else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) else var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) end end if i == 1 then mycalc=math.abs(var) myminus=minus else mycalc,myminus=rawCalcOperation(lastop,mycalc,var,myminus,minus) end end i=i+1 end setTotalValue({mycalc,myminus}) autoCalculateActive=false autoCalculateWait=Wait.time(autocalcOperation,1.0) end end end function debugme() log(extendCounterObjs) log(extendCounterCoin) if autoCalculateList != nil then for i, obj in ipairs(autoCalculateList) do local guid=obj.getGUID() local times=#autoCalculateList Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 0) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 1) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 2) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 3) end else log("nil") end local a,b=readDesc() log(a) log(b) end function extflash(tab) if tab[1] == nil then for i=1, 7 do Wait.time(function() self.highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end else for i=1, 7 do Wait.time(function() self.highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end extset(tab) end function extset(tab) extendCounterObjs=tab[1] updateContextMenu() end function scriptext(tab) if #tab[1] >= tab[2] then extendCounterObjs=tab[1] if #tab[1] > tab[2] then if string.sub(tab[1][tab[2]+1].script_code,tab[1][tab[2]+1].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or tab[1][tab[2]+1].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then tab[1][tab[2]+1].call("scriptext",{tab[1],tab[2]+1}) else -- end end updateContextMenu() end end function scriptcoin(coin) extendCounterCoin=coin[1] if #coin > 1 then if coin[2] != nil then invertcoin=coin[2] end if #coin > 2 then if coin[3] != nil then coinzero=coin[3] end end end end function createButtons(buttonlist,whatlist) self.clearButtons() local bgcol=self.getColorTint() local test=(bgcol.r * 0.3 + bgcol.r * 0.3 * (1-bgcol.g) + bgcol.g + bgcol.b * 0.4 > 0.925) local txtcol=test and Color(1,1,1) or Color(0,0,0) local buttcol=test and Color(0.2,0.2,0.2) or Color(0.8,0.8,0.8) local butthov=Color(0.5,0.5,0.5) --[[ self.createButton({ click_function=nil, function_owner=self, label=" ", position=Vector(0,0.2,-0.4-(math.ceil(#buttonlist/2)*0.08-0.08)), scale=Vector(0.1,1,0.1), width=4500, height=800*math.ceil(#buttonlist/2)+200, color={bgcol.r,bgcol.g,bgcol.b}, hover_color={bgcol.r,bgcol.g,bgcol.b}, press_color={bgcol.r,bgcol.g,bgcol.b} })]] local buttonorginpos=Vector(0.32,0.201,-0.41) local frame={ click_function="button", function_owner=self, label=" ", font_size=400, position=buttonorginpos, rotation=Vector(0,180,0), scale=Vector(0.1,1,0.1), width=1000, height=600, color={buttcol.r,buttcol.g,buttcol.b}, hover_color={butthov.r,butthov.g,butthov.b}, press_color={butthov.r,butthov.g,butthov.b}, font_color={txtcol.r,txtcol.g,txtcol.b} } local i=1 local slot=0 local line=0 local halfi=0 local function slothand(slot,lablen) if lablen == 1 then if slot == 0 then return 0 elseif slot == 1 then return -0.21 elseif slot == 2 then return -0.43 elseif slot == 3 then return -0.64 end elseif lablen == 2 then if slot == 0 then return -0.105 elseif slot == 1 then return -0.32 elseif slot == 2 then return -0.535 end elseif lablen == 3 then if slot == 0 then return -0.21 elseif slot == 1 then return -0.43 end elseif lablen == 4 then return -0.32 end end while i <= #buttonlist do local lastone=i == #buttonlist local curra,currb local test=whatlist[i] == "" if test then curra,currb=makecopytab(frame,1),makecopytab(frame,1) else curra=makecopytab(frame,1) end local formatted local formtype=numinter(buttonlist[i],nil,true) if formtype == "1" then formatted=string.format("%d",buttonlist[i]) else formatted=buttonlist[i] end local poslab=(test and "+" or (whatlist[i]))..formatted local neglab="-"..formatted local lablen=math.ceil(string.len(poslab)/4.5) if lablen > 4 then lablen=4; end curra.click_function=curra.click_function..(i-1+halfi)*2 if test then currb.click_function=currb.click_function..(i-1+halfi)*2+1 attachIndex("button",(i-1+halfi)*2) attachIndex("button",(i-1+halfi)*2+1) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=neglab if slot+lablen > 4 then line=line+1; slot=0; end currb.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) currb.width=lablen * currb.width currb.label=poslab self.createButton(curra) self.createButton(currb) else attachIndex("button",(i-1+halfi)*2) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=poslab self.createButton(curra) halfi=halfi-0.5 end i=i+1 end end function dummy() end function attachIndex(click_function, index) -- function to create multiple versions of function local fn_name = click_function .. index _G[fn_name] = function(obj, player_color, alt_click) _G[click_function](obj, player_color, alt_click, index) end return fn_name end function getTotalValue() if extendCounterObjs == nil then if extendCounterCoin == nil then local var=tonumber(self.getValue()) or 0 return var,var < 0,1 else local minus local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end return (minus and -math.abs(tonumber(self.getValue()) or 0) or math.abs(tonumber(self.getValue()) or 0)),minus,1 end else local meCounterIndex local i=1 while i <= #extendCounterObjs do if extendCounterObjs[i] == self then meCounterIndex=i end if extendCounterObjs[i] == nil then log("linked counter operation, counter "..i.." removed.") table.remove(extendCounterObjs,i) i=i-1 end i=i+1 end if #extendCounterObjs <= 1 then printToAll("[ff0000]ERROR:[-]Only one counter left, and started linkked counter operation.") extendCounterObjs=nil updateContextMenu() return getTotalValue() end if meCounterIndex == nil then printToAll("[ff0000]ERROR:[-]did not find index of counter."); return nil,nil,nil end local var=0 i=#extendCounterObjs local minus if extendCounterCoin == nil then minus=false else local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end end while i >= 1 do var=math.abs(tonumber(extendCounterObjs[i].getValue()) or 0) + var * 10000 i=i-1 end return (minus and -var or var),minus,meCounterIndex end end function setTotalValue(tab) local var,minus if type(tab).."" == "table" then if #tab >= 1 then var=tab[1] end if #tab >= 2 then minus=tab[2] end else log("setTotalValue:not a table") end if extendCounterObjs == nil then if minus == nil then minus=var < 0 end if minus and extendCounterCoin == nil then var=math.abs(var) % (minus and 1000 or 10000) elseif extendCounterCoin != nil then var=math.abs(var) % 10000 local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end if extendCounterCoin == nil then self.setValue(minus and -var or var) else self.setValue(var) end else if minus == nil then minus=var < 0 end var=var % math.pow(10000,#extendCounterObjs) if minus and extendCounterCoin == nil then var=math.pow(10000,#extendCounterObjs) - var elseif extendCounterCoin != nil then local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end i=#extendCounterObjs while i >= 1 do extendCounterObjs[i].setValue(math.floor(var/math.pow(10000,i-1)) % 10000) i=i-1 end end end function button(obj, col, alt_click, index) local list=self.getButtons() local var,minus,meCounterIndex=getTotalValue() local currlabel=list[index+1].label local oplett=string.sub(currlabel,1,1) local addable=numinter(string.sub(currlabel,2),0) var,minus=rawCalcOperation(oplett,var,addable * math.pow(10000,meCounterIndex-1),minus,false) setTotalValue({var,minus}) end function wrapCalcOperation(tab) local a,b,c,d,e if type(tab).."" == "table" then if #tab >= 1 then a=tab[1] end if #tab >= 2 then b=tab[2] end if #tab >= 3 then c=tab[3] end if #tab >= 4 then d=tab[4] end if #tab >= 5 then e=tab[5] end for name, item in pairs(tab) do if name == "oplett" then a=item elseif name == "var" then b=item elseif name == "addable" then c=item elseif name == "minus" then d=item elseif name == "addmeg" then e=item end end local var,minus=rawCalcOperation(a,b,c,d,e) return var,minus else log("wrapCalcOperation:not a table") return nil,nil end end function rawCalcOperation(oplett,var,addable,minus,addneg) if minus == nil then if var < 0 then minus=true else minus=false end end if addneg == nil then if addable < 0 then addneg=true else addneg=false end end if isOperator(oplett) then -- if oplett == "+" or oplett == "-" then -- if oplett == "-" and minus then -- oplett="+" -- elseif oplett == "+" and minus then -- oplett="-" -- end -- end else log("rawCalcOperation:Wrong operator") end if minus == addneg then local pah if oplett == "-" and minus then oplett = "+" end pah,var=isOperator(oplett,var,addable) else local pah if oplett == "-" then oplett = "+" elseif oplett == "+" then oplett = "-" end if minus then -- addable positive, var negative pah,var=isOperator(oplett,var,addable) else -- addable negative, var positive pah,var=isOperator(oplett,var,addable) end end if coinzero == 0 then if var < 0 then minus=not minus end elseif coinzero == -1 then if var < 0 then minus=not minus elseif 0 == var then minus=true end elseif coinzero == 1 then if var < 0 then minus=not minus elseif 0 == var then minus=false end elseif coinzero == 2 then if var >= 0 then minus=not minus end elseif coinzero == -2 then if var < 0 then minus=not minus end end return math.abs(var),minus end function isOperator(str,a,b) if type(str).."" == "string" then if string.len(str) == 1 then if type(a).."" == "number" and type(b).."" == "number" then a,b=math.abs(a),math.abs(b) if str == "+" then return true,a+b elseif str == "-" then return true,a-b elseif str == "*" then local pa,pb=a%100000000,b%100000000 local ba,bb=(a-pa)/100000000,(b-pb)/100000000 return true,pa*pb + ((ba*pb)%100000000)*100000000 + ((bb*pa)%100000000)*100000000 elseif str == "/" then return true,math.floor(a/b) elseif str == "&" then local ta,tb=a,b local i=0 local num=0 while ta != 0 and tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == cb and ca == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "|" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == 1 or cb == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "^" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if (ca == 1 and cb == 0) or (ca == 0 and cb == 1) then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "%" then return true,a%b elseif str == "<" then if b == 0 then return true,a end return true,a * math.pow(2,b) elseif str == ">" then if b == 0 then return true,a end return true,math.floor(a / math.pow(2,b)) elseif str == "p" then return true,math.floor(math.pow(a,b)) elseif str == "r" then return true,math.floor(math.pow(a,1.0/b)) end else if str == "+" then return true end if str == "-" then return true end if str == "*" then return true end if str == "/" then return true end if str == "&" then return true end if str == "|" then return true end if str == "^" then return true end if str == "%" then return true end if str == "<" then return true end if str == ">" then return true end if str == "p" then return true end if str == "r" then return true end end else log("isOperator:only one mark accepted ("..str..")") end else log("isOperator:only strings (of one character) accepted") end return false end function numinter(num,default,indentify) if type(num).."" == "number" then return num end if type(num).."" == "string" then local check="0123456789abcdefghijklmnopqrstuvwxyz" local out=nil if string.sub(num,1,1) == "0" then --hex or octaconal if string.sub(num,2,2) == "x" then --hex (base 16) if indentify then return "x" end local i=3 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:hex:not regonized character (".. c ..")"); elseif f >= 1 and f <= 16 then out=(out or 0) * 16 + f - 1 else log("numinter:hex:character out of bounds (".. (f-1) .. ")") end i=i+1 end else --octaconal (base 8) if indentify then return "0" end local i=2 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:octa:not regonized character (".. c ..")"); elseif f >= 1 and f <= 8 then out=(out or 0) * 8 + f - 1 else log("numinter:octa:character out of bounds (".. (f-1) .. "),(".. c ..")") end i=i+1 end end else if indentify then return "1" end out=tonumber(num) end if out == nil then return default else return out end end return default end function readDesc() local buttonlist={} local whatlist={} local desc=self.getDescription() or "" local txtstep=string.find(desc,",",1,true) if txtstep != nil then local prevstep repeat local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),txtstep-1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end prevstep=txtstep txtstep=string.find(desc,",",txtstep+1,true) until txtstep == nil or txtstep == string.len(desc) if textstep == nil then local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),string.len(desc)) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end elseif string.len(desc) > 0 then local poper=string.sub(desc,1,1) local test=isOperator(poper) local num=string.sub(desc,test and 2 or 1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end return buttonlist,whatlist end function makecopytab(tab,depth) local mydepth=depth or 0 if mydepth < 0 then log("this should not have been called. makecopytab") log(tab) return nil end local newtab={} if type(tab).."" == "table" then for x, val in pairs(tab) do if type(x).."" == "number" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then table.insert(newtab,x,Vector(tab[x])) else if mydepth > 0 then table.insert(newtab,x,makecopytab(tab[x],mydepth-1)) else table.insert(newtab,x,{}) end end else table.insert(newtab,x,tab[x]) end elseif type(x).."" == "string" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then newtab[x]=Vector(tab[x]) else if mydepth > 0 then newtab[x]=makecopytab(tab[x],mydepth-1) else newtab[x]={} end end else newtab[x]=tab[x] end end end else return tab end return newtab end function vectorRotate(vec,rot) return vec:rotateOver("z",rot.z):rotateOver("x",rot.x):rotateOver("y",rot.y) end function vectorIRotate(vec,rot) return vec:rotateOver("y",rot.y):rotateOver("x",rot.x):rotateOver("z",rot.z) end function vectorToLocal(target,objvec,objscale,objrot) local copy=Vector(target) copy=copy-(objvec or Vector(0,0,0)) copy=vectorIRotate(copy,(objrot or Vector(0,0,0)):inverse()) local tmp=objscale or Vector(1,1,1) copy=Vector(copy.x / tmp.x,copy.y / tmp.y, copy.z / tmp.z) return copy end function wrapVectorToLocal(tab) return vectorToLocal(tab[1],tab[2],tab[3],tab[4]) end function findInRadiusBy(pos, radius, func, debug) --by MrStump https://steamcommunity.com/sharedfiles/filedetails/?id=752690530&searchtext=lua --if DEBUG then log(" findInRadiusBy(): just called") end local radius = (radius or 1) local objList = Physics.cast({ origin=pos, direction={0,1,0}, type=2, size={radius,radius,radius}, max_distance=0, debug=(debug or false) }) local refinedList = {} for _, obj in ipairs(objList) do if func == nil then if obj.hit_object.type != "Surface" then -- Finaryman Mod table.insert(refinedList, obj.hit_object) end else if func(obj.hit_object) and obj.hit_object.type != "Surface" then --Finaryman Mod table.insert(refinedList, obj.hit_object) end end end return refinedList endLuaScriptState[]XmlUI192Ó¥GUID4e97f5NameCounterTransform‰posX#ÀposY \ºí?posZ@@ÀrotX {>rotY @AT¿rotZöÉz¾scaleX€ÿÿû?scaleY€ÿÿû?scaleZ€ÿÿû?NicknameMoneyDescription 2,5,10,25GMNotesAltLookAngle&xyzColorDiffuse&r <5¾?g€Âõà?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCountervalueLuaScriptq£function onLoad(str) --In code settings-- invertcoin=false --old negative value is now positive and old positive value is now negative coinzero=-2 --0 > toggle when beond zero, -1 > zero is negative, 1 > zero is positive, 2 > toggle when reached zero, -2 > zero is special autoconnect=true --allow autoconnecting by putting counters next to each other howfaraconn=0.6 --how far autoconnect works (object scale affects this) showcalcround=true --show autocalculation list on hover --End of settings--- savechanged=false local start=false SETTINGS_POS=string.find(self.script_code,"--End of settings---") self.setVar("SETTINGS_POS",SETTINGS_POS) if str != "" and str != nil then local data=JSON.decode(str) for name, info in pairs(data) do if name == "extendCounterObjs" then if type(info).."" == "table" then if #info > 1 then extendCounterObjs={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(extendCounterObjs,obj) end end if #extendCounterObjs < 2 then extendCounterObjs=nil end end end end if name == "extendCounterCoin" then local obj=getObjectFromGUID(info) if obj then extendCounterCoin=obj end end if name == "autoCalculateList" then if type(info).."" == "table" then if #info > 2 then autoCalculateList={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(autoCalculateList,obj) end end if #autoCalculateList < 3 then autoCalculateList=nil else start=true end end end end end end self.setVar("whatIAm","Counter") self.setVar("Supports_getTotalValue",true) self.setVar("whatIAmSpecfically","[finmod]Advanced Counter Mark II") watchDesc() updateContextMenu() if start then autoCalculateActive=false; autocalcOperation(); end end function onSave() local objs={} local autol={} local rettab={} local coin if savechanged then if extendCounterCoin then coin=extendCounterCoin.getGUID() end if type(extendCounterObjs).."" == "table" then for _, obj in ipairs(extendCounterObjs) do if obj then table.insert(objs,obj.getGUID()) end end end if type(autoCalculateList).."" == "table" then for _, obj in ipairs(autoCalculateList) do if obj then table.insert(autol,obj.getGUID()) end end end if #objs > 1 then rettab["extendCounterObjs"]=objs end if coin then rettab["extendCounterCoin"]=coin end if #autol > 2 then rettab["autoCalculateList"]=autol end savechanged=false return JSON.encode(rettab) else return self.script_state end end function getAnyVar(tab) return _G[tab[1]] end function setAnyVar(tab) _G[tab[1]]=tab[2] end function onHover(col) if autoCalculateList != nil and showcalcround then local showme={ color=Color(1,1,1), thickness=0.1, rotation=Vector(0,0,0), points={} } local pos=self.getPosition()+Vector(0,0.5,0) local ipos=self.getPosition()-Vector(0,1.5,0) local prevvec=vectorToLocal(pos,self.getPosition(),self.getScale(),self.getRotation()) local list={} i=#autoCalculateList while i > 0 do showme.color=Color(1,1,1):lerp(Color(0,0,1),(#autoCalculateList-i)/(#autoCalculateList-1)) table.insert(list,makecopytab(showme,1)) list[#autoCalculateList-i+1].points[1]=prevvec local obj=autoCalculateList[i] list[#autoCalculateList-i+1].points[2]=vectorToLocal(obj.getPosition(),ipos,self.getScale()*Vector(3,3,3),self.getRotation()) prevvec=list[#autoCalculateList-i+1].points[2] i=i-1 end self.setVectorLines(list) Wait.time(function() self.setVectorLines() end, 3.0) end end function onPickUp(color) if type(extendCounterObjs).."" == "table" then local amount=#extendCounterObjs local selob=Player[color].getSelectedObjects() if selob then if #selob == amount then for i=1, amount do local test = false for x=1, amount do if selob[i] == extendCounterObjs[x] then test=true end end if test then return end end end end for i, obj in ipairs(extendCounterObjs) do if obj then if string.sub(obj.script_code,obj.getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or obj.getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then obj.call("extflash",{nil}) obj.call("updateContextMenu") else local guid=obj.getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end end end end printToAll("broke connection of ".. amount .." counters.") end end function onDrop(color) startChecking() end function startChecking() if autoconnect then preCheck(os.time()+3) end end function preCheck(secs) if os.time() < secs then if not self.resting and checkWait == nil then checkWait=Wait.time(function() preCheck(secs) end,0.1) else checkWait=nil checkConnections() end else checkWait=nil end end function checkConnections() local finallist={self} local bd=self.getBounds() local scale=self.getScale() local x=bd.size.x / 2.0 local rot=self.getRotation() local left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) local right=Vector()-left local cpos=self.getPosition() local tmppos=cpos local test=true while test do local list=findInRadiusBy(tmppos+left,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,list[1]) else test=false end end tmppos=cpos test=true while test do local list=findInRadiusBy(tmppos+right,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 right=Vector(x+(howfaraconn+0.5)*scale.x,-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,1,list[1]) else test=false end end if #finallist <= 1 then return end local coin=extendCounterCoin for i=1,#finallist do if string.sub(finallist[i].script_code,finallist[i].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or finallist[i].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then finallist[i].call("extflash",{finallist}) if coin then finallist[i].call("scriptcoin",{coin,invertcoin,coinzero}) end else local guid=finallist[i].getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end end printToAll("Connected ".. #finallist .." counters.") end function watchDesc() if savedDesc != self.getDescription() then local a,b=readDesc() createButtons(a,b) savedDesc=self.getDescription() end if savedTint != self.getColorTint() then local a,b=readDesc() createButtons(a,b) savedTint=self.getColorTint() end Wait.time(watchDesc,0.5) end function updateContextMenu() self.clearContextMenu() self.addContextMenuItem("extend counter",extendc) if extendCounterObjs != nil then self.addContextMenuItem("clear",function() local a,minus,c=getTotalValue(); if coinzero == -1 then minus=true elseif coinzero == 1 then minus=false elseif coinzero == 2 then minus=not minus end setTotalValue({0,minus}) end) end self.addContextMenuItem("make autocalc",autocalc) savechanged=true end function extendc(col) if col == nil then extendCounterObjs=nil return end extendCounterObjs=Player[col].getSelectedObjects() extendCounterCoin=nil if extendCounterObjs != nil then if #extendCounterObjs <= 1 then extendCounterObjs=nil elseif #extendCounterObjs >= 2 then -- if self != extendCounterObjs[1] then -- printToAll("[ff0000]ERROR:[-]select smallest counter first, and from smallest counter right click menu.") -- return -- end if extendCounterObjs[i].type.."" != "Counter" then local i=1 while i <= #extendCounterObjs do if string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) and extendCounterObjs[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then local typetest=extendCounterObjs[i].type.."" == "Counter" or (extendCounterObjs[i].getVar("whatIAm") == "Counter") if i == 2 then if i == #extendCounterObjs then extendCounterCoin=extendCounterObjs[#extendCounterObjs] extendCounterObjs=nil return end elseif i == #extendCounterObjs and not typetest then log("LinkkingCounters:we assume this is coin (negitve display)") extendCounterCoin=extendCounterObjs[#extendCounterObjs] table.remove(extendCounterObjs) elseif typetest then printToAll("[ff0000]ERROR:[-]Unknown counter (possibly unexpected behaviour).") else table.remove(extendCounterObjs,i) i=i-1 end elseif string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) then printToAll("[ff0000]ERROR:[-]Counters not the same version (Advanced Counter Mark II) (possibly unexpected behaviour).") end i=i+1 end if #extendCounterObjs >= 2 then extendCounterObjs[1].call("scriptext",{extendCounterObjs,1}) end for i=1, #extendCounterObjs do if extendCounterObjs[i] != self then extendCounterObjs[i].call("scriptcoin",{extendCounterCoin,invertcoin,coinzero}) end end end end updateContextMenu() end function autocalc(col) savechanged=true autoCalculateList=nil if col == nil then return end autoCalculateList=Player[col].getSelectedObjects() Player[col].clearSelectedObjects() if autoCalculateList == nil then return end local i=1 while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i != #autoCalculateList then local test=isOperator(autoCalculateList[i].getName()) if not test then test=isOperator(autoCalculateList[i].getDescription()) end if not test then printToAll("[ff0000]ERROR:[-]autocalc: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) else local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,0),0.45) end, i*0.3+0.7) end else if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then log("non Advanced Counter Mark II detected (or too old version). "..i) else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then log("other version of Advanced Counter Mark II detected. "..i) else log("[00ff00]OK:[-]same version of Advanced Counter Mark II detected. "..i) end end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) end i=i+1 end log(autoCalculateList) table.remove(autoCalculateList) -- remove self if #autoCalculateList > 1 and ((#autoCalculateList % 2) == 1) then autoCalculateActive=false autocalcOperation() else printToAll("[ff0000]ERROR:[-] ".. #autoCalculateList .." long list failed (dropped). Select odd number of objects, starting from counter, then finally select counter to display the value (paired number of selected objects).") autoCalculateList=nil end end function autocalcOperation() if autoCalculateList != nil then if not autoCalculateActive then autoCalculateActive=true local i=1 local lastop local mycalc,myminus=0,false while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i == #autoCalculateList then printToAll("[ff0000]ERROR:[-]autocalcOperation: last one cannot be operator.") end local test=isOperator(autoCalculateList[i].getName()) if test then lastop=autoCalculateList[i].getName() else test=isOperator(autoCalculateList[i].getDescription()) if test then lastop=autoCalculateList[i].getDescription() else printToAll("[ff0000]ERROR:[-]autocalcOperation: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end end else local var,minus,index if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" and not autoCalculateList[i].getVar("Supports_getTotalValue") then var=autoCalculateList[i].getValue() minus=var < 0 else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) else var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) end end if i == 1 then mycalc=math.abs(var) myminus=minus else mycalc,myminus=rawCalcOperation(lastop,mycalc,var,myminus,minus) end end i=i+1 end setTotalValue({mycalc,myminus}) autoCalculateActive=false autoCalculateWait=Wait.time(autocalcOperation,1.0) end end end function debugme() log(extendCounterObjs) log(extendCounterCoin) if autoCalculateList != nil then for i, obj in ipairs(autoCalculateList) do local guid=obj.getGUID() local times=#autoCalculateList Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 0) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 1) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 2) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 3) end else log("nil") end local a,b=readDesc() log(a) log(b) end function extflash(tab) if tab[1] == nil then for i=1, 7 do Wait.time(function() self.highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end else for i=1, 7 do Wait.time(function() self.highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end extset(tab) end function extset(tab) extendCounterObjs=tab[1] updateContextMenu() end function scriptext(tab) if #tab[1] >= tab[2] then extendCounterObjs=tab[1] if #tab[1] > tab[2] then if string.sub(tab[1][tab[2]+1].script_code,tab[1][tab[2]+1].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or tab[1][tab[2]+1].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then tab[1][tab[2]+1].call("scriptext",{tab[1],tab[2]+1}) else -- end end updateContextMenu() end end function scriptcoin(coin) extendCounterCoin=coin[1] if #coin > 1 then if coin[2] != nil then invertcoin=coin[2] end if #coin > 2 then if coin[3] != nil then coinzero=coin[3] end end end end function createButtons(buttonlist,whatlist) self.clearButtons() local bgcol=self.getColorTint() local test=(bgcol.r * 0.3 + bgcol.r * 0.3 * (1-bgcol.g) + bgcol.g + bgcol.b * 0.4 > 0.925) local txtcol=test and Color(1,1,1) or Color(0,0,0) local buttcol=test and Color(0.2,0.2,0.2) or Color(0.8,0.8,0.8) local butthov=Color(0.5,0.5,0.5) --[[ self.createButton({ click_function=nil, function_owner=self, label=" ", position=Vector(0,0.2,-0.4-(math.ceil(#buttonlist/2)*0.08-0.08)), scale=Vector(0.1,1,0.1), width=4500, height=800*math.ceil(#buttonlist/2)+200, color={bgcol.r,bgcol.g,bgcol.b}, hover_color={bgcol.r,bgcol.g,bgcol.b}, press_color={bgcol.r,bgcol.g,bgcol.b} })]] local buttonorginpos=Vector(0.32,0.201,-0.41) local frame={ click_function="button", function_owner=self, label=" ", font_size=400, position=buttonorginpos, rotation=Vector(0,180,0), scale=Vector(0.1,1,0.1), width=1000, height=600, color={buttcol.r,buttcol.g,buttcol.b}, hover_color={butthov.r,butthov.g,butthov.b}, press_color={butthov.r,butthov.g,butthov.b}, font_color={txtcol.r,txtcol.g,txtcol.b} } local i=1 local slot=0 local line=0 local halfi=0 local function slothand(slot,lablen) if lablen == 1 then if slot == 0 then return 0 elseif slot == 1 then return -0.21 elseif slot == 2 then return -0.43 elseif slot == 3 then return -0.64 end elseif lablen == 2 then if slot == 0 then return -0.105 elseif slot == 1 then return -0.32 elseif slot == 2 then return -0.535 end elseif lablen == 3 then if slot == 0 then return -0.21 elseif slot == 1 then return -0.43 end elseif lablen == 4 then return -0.32 end end while i <= #buttonlist do local lastone=i == #buttonlist local curra,currb local test=whatlist[i] == "" if test then curra,currb=makecopytab(frame,1),makecopytab(frame,1) else curra=makecopytab(frame,1) end local formatted local formtype=numinter(buttonlist[i],nil,true) if formtype == "1" then formatted=string.format("%d",buttonlist[i]) else formatted=buttonlist[i] end local poslab=(test and "+" or (whatlist[i]))..formatted local neglab="-"..formatted local lablen=math.ceil(string.len(poslab)/4.5) if lablen > 4 then lablen=4; end curra.click_function=curra.click_function..(i-1+halfi)*2 if test then currb.click_function=currb.click_function..(i-1+halfi)*2+1 attachIndex("button",(i-1+halfi)*2) attachIndex("button",(i-1+halfi)*2+1) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=neglab if slot+lablen > 4 then line=line+1; slot=0; end currb.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) currb.width=lablen * currb.width currb.label=poslab self.createButton(curra) self.createButton(currb) else attachIndex("button",(i-1+halfi)*2) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=poslab self.createButton(curra) halfi=halfi-0.5 end i=i+1 end end function dummy() end function attachIndex(click_function, index) -- function to create multiple versions of function local fn_name = click_function .. index _G[fn_name] = function(obj, player_color, alt_click) _G[click_function](obj, player_color, alt_click, index) end return fn_name end function getTotalValue() if extendCounterObjs == nil then if extendCounterCoin == nil then local var=tonumber(self.getValue()) or 0 return var,var < 0,1 else local minus local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end return (minus and -math.abs(tonumber(self.getValue()) or 0) or math.abs(tonumber(self.getValue()) or 0)),minus,1 end else local meCounterIndex local i=1 while i <= #extendCounterObjs do if extendCounterObjs[i] == self then meCounterIndex=i end if extendCounterObjs[i] == nil then log("linked counter operation, counter "..i.." removed.") table.remove(extendCounterObjs,i) i=i-1 end i=i+1 end if #extendCounterObjs <= 1 then printToAll("[ff0000]ERROR:[-]Only one counter left, and started linkked counter operation.") extendCounterObjs=nil updateContextMenu() return getTotalValue() end if meCounterIndex == nil then printToAll("[ff0000]ERROR:[-]did not find index of counter."); return nil,nil,nil end local var=0 i=#extendCounterObjs local minus if extendCounterCoin == nil then minus=false else local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end end while i >= 1 do var=math.abs(tonumber(extendCounterObjs[i].getValue()) or 0) + var * 10000 i=i-1 end return (minus and -var or var),minus,meCounterIndex end end function setTotalValue(tab) local var,minus if type(tab).."" == "table" then if #tab >= 1 then var=tab[1] end if #tab >= 2 then minus=tab[2] end else log("setTotalValue:not a table") end if extendCounterObjs == nil then if minus == nil then minus=var < 0 end if minus and extendCounterCoin == nil then var=math.abs(var) % (minus and 1000 or 10000) elseif extendCounterCoin != nil then var=math.abs(var) % 10000 local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end if extendCounterCoin == nil then self.setValue(minus and -var or var) else self.setValue(var) end else if minus == nil then minus=var < 0 end var=var % math.pow(10000,#extendCounterObjs) if minus and extendCounterCoin == nil then var=math.pow(10000,#extendCounterObjs) - var elseif extendCounterCoin != nil then local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end i=#extendCounterObjs while i >= 1 do extendCounterObjs[i].setValue(math.floor(var/math.pow(10000,i-1)) % 10000) i=i-1 end end end function button(obj, col, alt_click, index) local list=self.getButtons() local var,minus,meCounterIndex=getTotalValue() local currlabel=list[index+1].label local oplett=string.sub(currlabel,1,1) local addable=numinter(string.sub(currlabel,2),0) var,minus=rawCalcOperation(oplett,var,addable * math.pow(10000,meCounterIndex-1),minus,false) setTotalValue({var,minus}) end function wrapCalcOperation(tab) local a,b,c,d,e if type(tab).."" == "table" then if #tab >= 1 then a=tab[1] end if #tab >= 2 then b=tab[2] end if #tab >= 3 then c=tab[3] end if #tab >= 4 then d=tab[4] end if #tab >= 5 then e=tab[5] end for name, item in pairs(tab) do if name == "oplett" then a=item elseif name == "var" then b=item elseif name == "addable" then c=item elseif name == "minus" then d=item elseif name == "addmeg" then e=item end end local var,minus=rawCalcOperation(a,b,c,d,e) return var,minus else log("wrapCalcOperation:not a table") return nil,nil end end function rawCalcOperation(oplett,var,addable,minus,addneg) if minus == nil then if var < 0 then minus=true else minus=false end end if addneg == nil then if addable < 0 then addneg=true else addneg=false end end if isOperator(oplett) then -- if oplett == "+" or oplett == "-" then -- if oplett == "-" and minus then -- oplett="+" -- elseif oplett == "+" and minus then -- oplett="-" -- end -- end else log("rawCalcOperation:Wrong operator") end if minus == addneg then local pah if oplett == "-" and minus then oplett = "+" end pah,var=isOperator(oplett,var,addable) else local pah if oplett == "-" then oplett = "+" elseif oplett == "+" then oplett = "-" end if minus then -- addable positive, var negative pah,var=isOperator(oplett,var,addable) else -- addable negative, var positive pah,var=isOperator(oplett,var,addable) end end if coinzero == 0 then if var < 0 then minus=not minus end elseif coinzero == -1 then if var < 0 then minus=not minus elseif 0 == var then minus=true end elseif coinzero == 1 then if var < 0 then minus=not minus elseif 0 == var then minus=false end elseif coinzero == 2 then if var >= 0 then minus=not minus end elseif coinzero == -2 then if var < 0 then minus=not minus end end return math.abs(var),minus end function isOperator(str,a,b) if type(str).."" == "string" then if string.len(str) == 1 then if type(a).."" == "number" and type(b).."" == "number" then a,b=math.abs(a),math.abs(b) if str == "+" then return true,a+b elseif str == "-" then return true,a-b elseif str == "*" then local pa,pb=a%100000000,b%100000000 local ba,bb=(a-pa)/100000000,(b-pb)/100000000 return true,pa*pb + ((ba*pb)%100000000)*100000000 + ((bb*pa)%100000000)*100000000 elseif str == "/" then return true,math.floor(a/b) elseif str == "&" then local ta,tb=a,b local i=0 local num=0 while ta != 0 and tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == cb and ca == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "|" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == 1 or cb == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "^" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if (ca == 1 and cb == 0) or (ca == 0 and cb == 1) then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "%" then return true,a%b elseif str == "<" then if b == 0 then return true,a end return true,a * math.pow(2,b) elseif str == ">" then if b == 0 then return true,a end return true,math.floor(a / math.pow(2,b)) elseif str == "p" then return true,math.floor(math.pow(a,b)) elseif str == "r" then return true,math.floor(math.pow(a,1.0/b)) end else if str == "+" then return true end if str == "-" then return true end if str == "*" then return true end if str == "/" then return true end if str == "&" then return true end if str == "|" then return true end if str == "^" then return true end if str == "%" then return true end if str == "<" then return true end if str == ">" then return true end if str == "p" then return true end if str == "r" then return true end end else log("isOperator:only one mark accepted ("..str..")") end else log("isOperator:only strings (of one character) accepted") end return false end function numinter(num,default,indentify) if type(num).."" == "number" then return num end if type(num).."" == "string" then local check="0123456789abcdefghijklmnopqrstuvwxyz" local out=nil if string.sub(num,1,1) == "0" then --hex or octaconal if string.sub(num,2,2) == "x" then --hex (base 16) if indentify then return "x" end local i=3 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:hex:not regonized character (".. c ..")"); elseif f >= 1 and f <= 16 then out=(out or 0) * 16 + f - 1 else log("numinter:hex:character out of bounds (".. (f-1) .. ")") end i=i+1 end else --octaconal (base 8) if indentify then return "0" end local i=2 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:octa:not regonized character (".. c ..")"); elseif f >= 1 and f <= 8 then out=(out or 0) * 8 + f - 1 else log("numinter:octa:character out of bounds (".. (f-1) .. "),(".. c ..")") end i=i+1 end end else if indentify then return "1" end out=tonumber(num) end if out == nil then return default else return out end end return default end function readDesc() local buttonlist={} local whatlist={} local desc=self.getDescription() or "" local txtstep=string.find(desc,",",1,true) if txtstep != nil then local prevstep repeat local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),txtstep-1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end prevstep=txtstep txtstep=string.find(desc,",",txtstep+1,true) until txtstep == nil or txtstep == string.len(desc) if textstep == nil then local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),string.len(desc)) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end elseif string.len(desc) > 0 then local poper=string.sub(desc,1,1) local test=isOperator(poper) local num=string.sub(desc,test and 2 or 1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end return buttonlist,whatlist end function makecopytab(tab,depth) local mydepth=depth or 0 if mydepth < 0 then log("this should not have been called. makecopytab") log(tab) return nil end local newtab={} if type(tab).."" == "table" then for x, val in pairs(tab) do if type(x).."" == "number" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then table.insert(newtab,x,Vector(tab[x])) else if mydepth > 0 then table.insert(newtab,x,makecopytab(tab[x],mydepth-1)) else table.insert(newtab,x,{}) end end else table.insert(newtab,x,tab[x]) end elseif type(x).."" == "string" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then newtab[x]=Vector(tab[x]) else if mydepth > 0 then newtab[x]=makecopytab(tab[x],mydepth-1) else newtab[x]={} end end else newtab[x]=tab[x] end end end else return tab end return newtab end function vectorRotate(vec,rot) return vec:rotateOver("z",rot.z):rotateOver("x",rot.x):rotateOver("y",rot.y) end function vectorIRotate(vec,rot) return vec:rotateOver("y",rot.y):rotateOver("x",rot.x):rotateOver("z",rot.z) end function vectorToLocal(target,objvec,objscale,objrot) local copy=Vector(target) copy=copy-(objvec or Vector(0,0,0)) copy=vectorIRotate(copy,(objrot or Vector(0,0,0)):inverse()) local tmp=objscale or Vector(1,1,1) copy=Vector(copy.x / tmp.x,copy.y / tmp.y, copy.z / tmp.z) return copy end function wrapVectorToLocal(tab) return vectorToLocal(tab[1],tab[2],tab[3],tab[4]) end function findInRadiusBy(pos, radius, func, debug) --by MrStump https://steamcommunity.com/sharedfiles/filedetails/?id=752690530&searchtext=lua --if DEBUG then log(" findInRadiusBy(): just called") end local radius = (radius or 1) local objList = Physics.cast({ origin=pos, direction={0,1,0}, type=2, size={radius,radius,radius}, max_distance=0, debug=(debug or false) }) local refinedList = {} for _, obj in ipairs(objList) do if func == nil then if obj.hit_object.type != "Surface" then -- Finaryman Mod table.insert(refinedList, obj.hit_object) end else if func(obj.hit_object) and obj.hit_object.type != "Surface" then --Finaryman Mod table.insert(refinedList, obj.hit_object) end end end return refinedList endLuaScriptState[]XmlUI193Ó¥GUIDe9e95dNameCounterTransform‰posX@À@ÀposY`\ºí?posZ@@ÀrotX Ç°µ¾rotY€ R¿rotZÀ!›¾scaleX€ÿÿû?scaleY€ÿÿû?scaleZ€ÿÿû?NicknameMoneyDescription 2,5,10,25GMNotesAltLookAngle&xyzColorDiffuse&r Zdë?g –™¹?b`^¸?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCountervalueLuaScriptq£function onLoad(str) --In code settings-- invertcoin=false --old negative value is now positive and old positive value is now negative coinzero=-2 --0 > toggle when beond zero, -1 > zero is negative, 1 > zero is positive, 2 > toggle when reached zero, -2 > zero is special autoconnect=true --allow autoconnecting by putting counters next to each other howfaraconn=0.6 --how far autoconnect works (object scale affects this) showcalcround=true --show autocalculation list on hover --End of settings--- savechanged=false local start=false SETTINGS_POS=string.find(self.script_code,"--End of settings---") self.setVar("SETTINGS_POS",SETTINGS_POS) if str != "" and str != nil then local data=JSON.decode(str) for name, info in pairs(data) do if name == "extendCounterObjs" then if type(info).."" == "table" then if #info > 1 then extendCounterObjs={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(extendCounterObjs,obj) end end if #extendCounterObjs < 2 then extendCounterObjs=nil end end end end if name == "extendCounterCoin" then local obj=getObjectFromGUID(info) if obj then extendCounterCoin=obj end end if name == "autoCalculateList" then if type(info).."" == "table" then if #info > 2 then autoCalculateList={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(autoCalculateList,obj) end end if #autoCalculateList < 3 then autoCalculateList=nil else start=true end end end end end end self.setVar("whatIAm","Counter") self.setVar("Supports_getTotalValue",true) self.setVar("whatIAmSpecfically","[finmod]Advanced Counter Mark II") watchDesc() updateContextMenu() if start then autoCalculateActive=false; autocalcOperation(); end end function onSave() local objs={} local autol={} local rettab={} local coin if savechanged then if extendCounterCoin then coin=extendCounterCoin.getGUID() end if type(extendCounterObjs).."" == "table" then for _, obj in ipairs(extendCounterObjs) do if obj then table.insert(objs,obj.getGUID()) end end end if type(autoCalculateList).."" == "table" then for _, obj in ipairs(autoCalculateList) do if obj then table.insert(autol,obj.getGUID()) end end end if #objs > 1 then rettab["extendCounterObjs"]=objs end if coin then rettab["extendCounterCoin"]=coin end if #autol > 2 then rettab["autoCalculateList"]=autol end savechanged=false return JSON.encode(rettab) else return self.script_state end end function getAnyVar(tab) return _G[tab[1]] end function setAnyVar(tab) _G[tab[1]]=tab[2] end function onHover(col) if autoCalculateList != nil and showcalcround then local showme={ color=Color(1,1,1), thickness=0.1, rotation=Vector(0,0,0), points={} } local pos=self.getPosition()+Vector(0,0.5,0) local ipos=self.getPosition()-Vector(0,1.5,0) local prevvec=vectorToLocal(pos,self.getPosition(),self.getScale(),self.getRotation()) local list={} i=#autoCalculateList while i > 0 do showme.color=Color(1,1,1):lerp(Color(0,0,1),(#autoCalculateList-i)/(#autoCalculateList-1)) table.insert(list,makecopytab(showme,1)) list[#autoCalculateList-i+1].points[1]=prevvec local obj=autoCalculateList[i] list[#autoCalculateList-i+1].points[2]=vectorToLocal(obj.getPosition(),ipos,self.getScale()*Vector(3,3,3),self.getRotation()) prevvec=list[#autoCalculateList-i+1].points[2] i=i-1 end self.setVectorLines(list) Wait.time(function() self.setVectorLines() end, 3.0) end end function onPickUp(color) if type(extendCounterObjs).."" == "table" then local amount=#extendCounterObjs local selob=Player[color].getSelectedObjects() if selob then if #selob == amount then for i=1, amount do local test = false for x=1, amount do if selob[i] == extendCounterObjs[x] then test=true end end if test then return end end end end for i, obj in ipairs(extendCounterObjs) do if obj then if string.sub(obj.script_code,obj.getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or obj.getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then obj.call("extflash",{nil}) obj.call("updateContextMenu") else local guid=obj.getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end end end end printToAll("broke connection of ".. amount .." counters.") end end function onDrop(color) startChecking() end function startChecking() if autoconnect then preCheck(os.time()+3) end end function preCheck(secs) if os.time() < secs then if not self.resting and checkWait == nil then checkWait=Wait.time(function() preCheck(secs) end,0.1) else checkWait=nil checkConnections() end else checkWait=nil end end function checkConnections() local finallist={self} local bd=self.getBounds() local scale=self.getScale() local x=bd.size.x / 2.0 local rot=self.getRotation() local left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) local right=Vector()-left local cpos=self.getPosition() local tmppos=cpos local test=true while test do local list=findInRadiusBy(tmppos+left,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,list[1]) else test=false end end tmppos=cpos test=true while test do local list=findInRadiusBy(tmppos+right,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 right=Vector(x+(howfaraconn+0.5)*scale.x,-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,1,list[1]) else test=false end end if #finallist <= 1 then return end local coin=extendCounterCoin for i=1,#finallist do if string.sub(finallist[i].script_code,finallist[i].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or finallist[i].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then finallist[i].call("extflash",{finallist}) if coin then finallist[i].call("scriptcoin",{coin,invertcoin,coinzero}) end else local guid=finallist[i].getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end end printToAll("Connected ".. #finallist .." counters.") end function watchDesc() if savedDesc != self.getDescription() then local a,b=readDesc() createButtons(a,b) savedDesc=self.getDescription() end if savedTint != self.getColorTint() then local a,b=readDesc() createButtons(a,b) savedTint=self.getColorTint() end Wait.time(watchDesc,0.5) end function updateContextMenu() self.clearContextMenu() self.addContextMenuItem("extend counter",extendc) if extendCounterObjs != nil then self.addContextMenuItem("clear",function() local a,minus,c=getTotalValue(); if coinzero == -1 then minus=true elseif coinzero == 1 then minus=false elseif coinzero == 2 then minus=not minus end setTotalValue({0,minus}) end) end self.addContextMenuItem("make autocalc",autocalc) savechanged=true end function extendc(col) if col == nil then extendCounterObjs=nil return end extendCounterObjs=Player[col].getSelectedObjects() extendCounterCoin=nil if extendCounterObjs != nil then if #extendCounterObjs <= 1 then extendCounterObjs=nil elseif #extendCounterObjs >= 2 then -- if self != extendCounterObjs[1] then -- printToAll("[ff0000]ERROR:[-]select smallest counter first, and from smallest counter right click menu.") -- return -- end if extendCounterObjs[i].type.."" != "Counter" then local i=1 while i <= #extendCounterObjs do if string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) and extendCounterObjs[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then local typetest=extendCounterObjs[i].type.."" == "Counter" or (extendCounterObjs[i].getVar("whatIAm") == "Counter") if i == 2 then if i == #extendCounterObjs then extendCounterCoin=extendCounterObjs[#extendCounterObjs] extendCounterObjs=nil return end elseif i == #extendCounterObjs and not typetest then log("LinkkingCounters:we assume this is coin (negitve display)") extendCounterCoin=extendCounterObjs[#extendCounterObjs] table.remove(extendCounterObjs) elseif typetest then printToAll("[ff0000]ERROR:[-]Unknown counter (possibly unexpected behaviour).") else table.remove(extendCounterObjs,i) i=i-1 end elseif string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) then printToAll("[ff0000]ERROR:[-]Counters not the same version (Advanced Counter Mark II) (possibly unexpected behaviour).") end i=i+1 end if #extendCounterObjs >= 2 then extendCounterObjs[1].call("scriptext",{extendCounterObjs,1}) end for i=1, #extendCounterObjs do if extendCounterObjs[i] != self then extendCounterObjs[i].call("scriptcoin",{extendCounterCoin,invertcoin,coinzero}) end end end end updateContextMenu() end function autocalc(col) savechanged=true autoCalculateList=nil if col == nil then return end autoCalculateList=Player[col].getSelectedObjects() Player[col].clearSelectedObjects() if autoCalculateList == nil then return end local i=1 while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i != #autoCalculateList then local test=isOperator(autoCalculateList[i].getName()) if not test then test=isOperator(autoCalculateList[i].getDescription()) end if not test then printToAll("[ff0000]ERROR:[-]autocalc: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) else local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,0),0.45) end, i*0.3+0.7) end else if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then log("non Advanced Counter Mark II detected (or too old version). "..i) else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then log("other version of Advanced Counter Mark II detected. "..i) else log("[00ff00]OK:[-]same version of Advanced Counter Mark II detected. "..i) end end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) end i=i+1 end log(autoCalculateList) table.remove(autoCalculateList) -- remove self if #autoCalculateList > 1 and ((#autoCalculateList % 2) == 1) then autoCalculateActive=false autocalcOperation() else printToAll("[ff0000]ERROR:[-] ".. #autoCalculateList .." long list failed (dropped). Select odd number of objects, starting from counter, then finally select counter to display the value (paired number of selected objects).") autoCalculateList=nil end end function autocalcOperation() if autoCalculateList != nil then if not autoCalculateActive then autoCalculateActive=true local i=1 local lastop local mycalc,myminus=0,false while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i == #autoCalculateList then printToAll("[ff0000]ERROR:[-]autocalcOperation: last one cannot be operator.") end local test=isOperator(autoCalculateList[i].getName()) if test then lastop=autoCalculateList[i].getName() else test=isOperator(autoCalculateList[i].getDescription()) if test then lastop=autoCalculateList[i].getDescription() else printToAll("[ff0000]ERROR:[-]autocalcOperation: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end end else local var,minus,index if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" and not autoCalculateList[i].getVar("Supports_getTotalValue") then var=autoCalculateList[i].getValue() minus=var < 0 else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) else var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) end end if i == 1 then mycalc=math.abs(var) myminus=minus else mycalc,myminus=rawCalcOperation(lastop,mycalc,var,myminus,minus) end end i=i+1 end setTotalValue({mycalc,myminus}) autoCalculateActive=false autoCalculateWait=Wait.time(autocalcOperation,1.0) end end end function debugme() log(extendCounterObjs) log(extendCounterCoin) if autoCalculateList != nil then for i, obj in ipairs(autoCalculateList) do local guid=obj.getGUID() local times=#autoCalculateList Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 0) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 1) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 2) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 3) end else log("nil") end local a,b=readDesc() log(a) log(b) end function extflash(tab) if tab[1] == nil then for i=1, 7 do Wait.time(function() self.highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end else for i=1, 7 do Wait.time(function() self.highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end extset(tab) end function extset(tab) extendCounterObjs=tab[1] updateContextMenu() end function scriptext(tab) if #tab[1] >= tab[2] then extendCounterObjs=tab[1] if #tab[1] > tab[2] then if string.sub(tab[1][tab[2]+1].script_code,tab[1][tab[2]+1].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or tab[1][tab[2]+1].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then tab[1][tab[2]+1].call("scriptext",{tab[1],tab[2]+1}) else -- end end updateContextMenu() end end function scriptcoin(coin) extendCounterCoin=coin[1] if #coin > 1 then if coin[2] != nil then invertcoin=coin[2] end if #coin > 2 then if coin[3] != nil then coinzero=coin[3] end end end end function createButtons(buttonlist,whatlist) self.clearButtons() local bgcol=self.getColorTint() local test=(bgcol.r * 0.3 + bgcol.r * 0.3 * (1-bgcol.g) + bgcol.g + bgcol.b * 0.4 > 0.925) local txtcol=test and Color(1,1,1) or Color(0,0,0) local buttcol=test and Color(0.2,0.2,0.2) or Color(0.8,0.8,0.8) local butthov=Color(0.5,0.5,0.5) --[[ self.createButton({ click_function=nil, function_owner=self, label=" ", position=Vector(0,0.2,-0.4-(math.ceil(#buttonlist/2)*0.08-0.08)), scale=Vector(0.1,1,0.1), width=4500, height=800*math.ceil(#buttonlist/2)+200, color={bgcol.r,bgcol.g,bgcol.b}, hover_color={bgcol.r,bgcol.g,bgcol.b}, press_color={bgcol.r,bgcol.g,bgcol.b} })]] local buttonorginpos=Vector(0.32,0.201,-0.41) local frame={ click_function="button", function_owner=self, label=" ", font_size=400, position=buttonorginpos, rotation=Vector(0,180,0), scale=Vector(0.1,1,0.1), width=1000, height=600, color={buttcol.r,buttcol.g,buttcol.b}, hover_color={butthov.r,butthov.g,butthov.b}, press_color={butthov.r,butthov.g,butthov.b}, font_color={txtcol.r,txtcol.g,txtcol.b} } local i=1 local slot=0 local line=0 local halfi=0 local function slothand(slot,lablen) if lablen == 1 then if slot == 0 then return 0 elseif slot == 1 then return -0.21 elseif slot == 2 then return -0.43 elseif slot == 3 then return -0.64 end elseif lablen == 2 then if slot == 0 then return -0.105 elseif slot == 1 then return -0.32 elseif slot == 2 then return -0.535 end elseif lablen == 3 then if slot == 0 then return -0.21 elseif slot == 1 then return -0.43 end elseif lablen == 4 then return -0.32 end end while i <= #buttonlist do local lastone=i == #buttonlist local curra,currb local test=whatlist[i] == "" if test then curra,currb=makecopytab(frame,1),makecopytab(frame,1) else curra=makecopytab(frame,1) end local formatted local formtype=numinter(buttonlist[i],nil,true) if formtype == "1" then formatted=string.format("%d",buttonlist[i]) else formatted=buttonlist[i] end local poslab=(test and "+" or (whatlist[i]))..formatted local neglab="-"..formatted local lablen=math.ceil(string.len(poslab)/4.5) if lablen > 4 then lablen=4; end curra.click_function=curra.click_function..(i-1+halfi)*2 if test then currb.click_function=currb.click_function..(i-1+halfi)*2+1 attachIndex("button",(i-1+halfi)*2) attachIndex("button",(i-1+halfi)*2+1) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=neglab if slot+lablen > 4 then line=line+1; slot=0; end currb.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) currb.width=lablen * currb.width currb.label=poslab self.createButton(curra) self.createButton(currb) else attachIndex("button",(i-1+halfi)*2) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=poslab self.createButton(curra) halfi=halfi-0.5 end i=i+1 end end function dummy() end function attachIndex(click_function, index) -- function to create multiple versions of function local fn_name = click_function .. index _G[fn_name] = function(obj, player_color, alt_click) _G[click_function](obj, player_color, alt_click, index) end return fn_name end function getTotalValue() if extendCounterObjs == nil then if extendCounterCoin == nil then local var=tonumber(self.getValue()) or 0 return var,var < 0,1 else local minus local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end return (minus and -math.abs(tonumber(self.getValue()) or 0) or math.abs(tonumber(self.getValue()) or 0)),minus,1 end else local meCounterIndex local i=1 while i <= #extendCounterObjs do if extendCounterObjs[i] == self then meCounterIndex=i end if extendCounterObjs[i] == nil then log("linked counter operation, counter "..i.." removed.") table.remove(extendCounterObjs,i) i=i-1 end i=i+1 end if #extendCounterObjs <= 1 then printToAll("[ff0000]ERROR:[-]Only one counter left, and started linkked counter operation.") extendCounterObjs=nil updateContextMenu() return getTotalValue() end if meCounterIndex == nil then printToAll("[ff0000]ERROR:[-]did not find index of counter."); return nil,nil,nil end local var=0 i=#extendCounterObjs local minus if extendCounterCoin == nil then minus=false else local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end end while i >= 1 do var=math.abs(tonumber(extendCounterObjs[i].getValue()) or 0) + var * 10000 i=i-1 end return (minus and -var or var),minus,meCounterIndex end end function setTotalValue(tab) local var,minus if type(tab).."" == "table" then if #tab >= 1 then var=tab[1] end if #tab >= 2 then minus=tab[2] end else log("setTotalValue:not a table") end if extendCounterObjs == nil then if minus == nil then minus=var < 0 end if minus and extendCounterCoin == nil then var=math.abs(var) % (minus and 1000 or 10000) elseif extendCounterCoin != nil then var=math.abs(var) % 10000 local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end if extendCounterCoin == nil then self.setValue(minus and -var or var) else self.setValue(var) end else if minus == nil then minus=var < 0 end var=var % math.pow(10000,#extendCounterObjs) if minus and extendCounterCoin == nil then var=math.pow(10000,#extendCounterObjs) - var elseif extendCounterCoin != nil then local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end i=#extendCounterObjs while i >= 1 do extendCounterObjs[i].setValue(math.floor(var/math.pow(10000,i-1)) % 10000) i=i-1 end end end function button(obj, col, alt_click, index) local list=self.getButtons() local var,minus,meCounterIndex=getTotalValue() local currlabel=list[index+1].label local oplett=string.sub(currlabel,1,1) local addable=numinter(string.sub(currlabel,2),0) var,minus=rawCalcOperation(oplett,var,addable * math.pow(10000,meCounterIndex-1),minus,false) setTotalValue({var,minus}) end function wrapCalcOperation(tab) local a,b,c,d,e if type(tab).."" == "table" then if #tab >= 1 then a=tab[1] end if #tab >= 2 then b=tab[2] end if #tab >= 3 then c=tab[3] end if #tab >= 4 then d=tab[4] end if #tab >= 5 then e=tab[5] end for name, item in pairs(tab) do if name == "oplett" then a=item elseif name == "var" then b=item elseif name == "addable" then c=item elseif name == "minus" then d=item elseif name == "addmeg" then e=item end end local var,minus=rawCalcOperation(a,b,c,d,e) return var,minus else log("wrapCalcOperation:not a table") return nil,nil end end function rawCalcOperation(oplett,var,addable,minus,addneg) if minus == nil then if var < 0 then minus=true else minus=false end end if addneg == nil then if addable < 0 then addneg=true else addneg=false end end if isOperator(oplett) then -- if oplett == "+" or oplett == "-" then -- if oplett == "-" and minus then -- oplett="+" -- elseif oplett == "+" and minus then -- oplett="-" -- end -- end else log("rawCalcOperation:Wrong operator") end if minus == addneg then local pah if oplett == "-" and minus then oplett = "+" end pah,var=isOperator(oplett,var,addable) else local pah if oplett == "-" then oplett = "+" elseif oplett == "+" then oplett = "-" end if minus then -- addable positive, var negative pah,var=isOperator(oplett,var,addable) else -- addable negative, var positive pah,var=isOperator(oplett,var,addable) end end if coinzero == 0 then if var < 0 then minus=not minus end elseif coinzero == -1 then if var < 0 then minus=not minus elseif 0 == var then minus=true end elseif coinzero == 1 then if var < 0 then minus=not minus elseif 0 == var then minus=false end elseif coinzero == 2 then if var >= 0 then minus=not minus end elseif coinzero == -2 then if var < 0 then minus=not minus end end return math.abs(var),minus end function isOperator(str,a,b) if type(str).."" == "string" then if string.len(str) == 1 then if type(a).."" == "number" and type(b).."" == "number" then a,b=math.abs(a),math.abs(b) if str == "+" then return true,a+b elseif str == "-" then return true,a-b elseif str == "*" then local pa,pb=a%100000000,b%100000000 local ba,bb=(a-pa)/100000000,(b-pb)/100000000 return true,pa*pb + ((ba*pb)%100000000)*100000000 + ((bb*pa)%100000000)*100000000 elseif str == "/" then return true,math.floor(a/b) elseif str == "&" then local ta,tb=a,b local i=0 local num=0 while ta != 0 and tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == cb and ca == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "|" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == 1 or cb == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "^" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if (ca == 1 and cb == 0) or (ca == 0 and cb == 1) then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "%" then return true,a%b elseif str == "<" then if b == 0 then return true,a end return true,a * math.pow(2,b) elseif str == ">" then if b == 0 then return true,a end return true,math.floor(a / math.pow(2,b)) elseif str == "p" then return true,math.floor(math.pow(a,b)) elseif str == "r" then return true,math.floor(math.pow(a,1.0/b)) end else if str == "+" then return true end if str == "-" then return true end if str == "*" then return true end if str == "/" then return true end if str == "&" then return true end if str == "|" then return true end if str == "^" then return true end if str == "%" then return true end if str == "<" then return true end if str == ">" then return true end if str == "p" then return true end if str == "r" then return true end end else log("isOperator:only one mark accepted ("..str..")") end else log("isOperator:only strings (of one character) accepted") end return false end function numinter(num,default,indentify) if type(num).."" == "number" then return num end if type(num).."" == "string" then local check="0123456789abcdefghijklmnopqrstuvwxyz" local out=nil if string.sub(num,1,1) == "0" then --hex or octaconal if string.sub(num,2,2) == "x" then --hex (base 16) if indentify then return "x" end local i=3 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:hex:not regonized character (".. c ..")"); elseif f >= 1 and f <= 16 then out=(out or 0) * 16 + f - 1 else log("numinter:hex:character out of bounds (".. (f-1) .. ")") end i=i+1 end else --octaconal (base 8) if indentify then return "0" end local i=2 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:octa:not regonized character (".. c ..")"); elseif f >= 1 and f <= 8 then out=(out or 0) * 8 + f - 1 else log("numinter:octa:character out of bounds (".. (f-1) .. "),(".. c ..")") end i=i+1 end end else if indentify then return "1" end out=tonumber(num) end if out == nil then return default else return out end end return default end function readDesc() local buttonlist={} local whatlist={} local desc=self.getDescription() or "" local txtstep=string.find(desc,",",1,true) if txtstep != nil then local prevstep repeat local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),txtstep-1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end prevstep=txtstep txtstep=string.find(desc,",",txtstep+1,true) until txtstep == nil or txtstep == string.len(desc) if textstep == nil then local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),string.len(desc)) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end elseif string.len(desc) > 0 then local poper=string.sub(desc,1,1) local test=isOperator(poper) local num=string.sub(desc,test and 2 or 1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end return buttonlist,whatlist end function makecopytab(tab,depth) local mydepth=depth or 0 if mydepth < 0 then log("this should not have been called. makecopytab") log(tab) return nil end local newtab={} if type(tab).."" == "table" then for x, val in pairs(tab) do if type(x).."" == "number" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then table.insert(newtab,x,Vector(tab[x])) else if mydepth > 0 then table.insert(newtab,x,makecopytab(tab[x],mydepth-1)) else table.insert(newtab,x,{}) end end else table.insert(newtab,x,tab[x]) end elseif type(x).."" == "string" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then newtab[x]=Vector(tab[x]) else if mydepth > 0 then newtab[x]=makecopytab(tab[x],mydepth-1) else newtab[x]={} end end else newtab[x]=tab[x] end end end else return tab end return newtab end function vectorRotate(vec,rot) return vec:rotateOver("z",rot.z):rotateOver("x",rot.x):rotateOver("y",rot.y) end function vectorIRotate(vec,rot) return vec:rotateOver("y",rot.y):rotateOver("x",rot.x):rotateOver("z",rot.z) end function vectorToLocal(target,objvec,objscale,objrot) local copy=Vector(target) copy=copy-(objvec or Vector(0,0,0)) copy=vectorIRotate(copy,(objrot or Vector(0,0,0)):inverse()) local tmp=objscale or Vector(1,1,1) copy=Vector(copy.x / tmp.x,copy.y / tmp.y, copy.z / tmp.z) return copy end function wrapVectorToLocal(tab) return vectorToLocal(tab[1],tab[2],tab[3],tab[4]) end function findInRadiusBy(pos, radius, func, debug) --by MrStump https://steamcommunity.com/sharedfiles/filedetails/?id=752690530&searchtext=lua --if DEBUG then log(" findInRadiusBy(): just called") end local radius = (radius or 1) local objList = Physics.cast({ origin=pos, direction={0,1,0}, type=2, size={radius,radius,radius}, max_distance=0, debug=(debug or false) }) local refinedList = {} for _, obj in ipairs(objList) do if func == nil then if obj.hit_object.type != "Surface" then -- Finaryman Mod table.insert(refinedList, obj.hit_object) end else if func(obj.hit_object) and obj.hit_object.type != "Surface" then --Finaryman Mod table.insert(refinedList, obj.hit_object) end end end return refinedList endLuaScriptState[]XmlUI194Ó¥GUIDb8baacNameCounterTransform‰posX€@ÀposYà[ºí?posZA@rotX`¬hL>rotY jR¿rotZ ¶°i¾scaleX€ÿÿû?scaleY€ÿÿû?scaleZ€ÿÿû?NicknameMoneyDescription 2,5,10,25GMNotesAltLookAngle&xyzColorDiffuse&r€Âõì?g€j¼ì?bÀÆ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCountervalueLuaScriptq£function onLoad(str) --In code settings-- invertcoin=false --old negative value is now positive and old positive value is now negative coinzero=-2 --0 > toggle when beond zero, -1 > zero is negative, 1 > zero is positive, 2 > toggle when reached zero, -2 > zero is special autoconnect=true --allow autoconnecting by putting counters next to each other howfaraconn=0.6 --how far autoconnect works (object scale affects this) showcalcround=true --show autocalculation list on hover --End of settings--- savechanged=false local start=false SETTINGS_POS=string.find(self.script_code,"--End of settings---") self.setVar("SETTINGS_POS",SETTINGS_POS) if str != "" and str != nil then local data=JSON.decode(str) for name, info in pairs(data) do if name == "extendCounterObjs" then if type(info).."" == "table" then if #info > 1 then extendCounterObjs={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(extendCounterObjs,obj) end end if #extendCounterObjs < 2 then extendCounterObjs=nil end end end end if name == "extendCounterCoin" then local obj=getObjectFromGUID(info) if obj then extendCounterCoin=obj end end if name == "autoCalculateList" then if type(info).."" == "table" then if #info > 2 then autoCalculateList={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(autoCalculateList,obj) end end if #autoCalculateList < 3 then autoCalculateList=nil else start=true end end end end end end self.setVar("whatIAm","Counter") self.setVar("Supports_getTotalValue",true) self.setVar("whatIAmSpecfically","[finmod]Advanced Counter Mark II") watchDesc() updateContextMenu() if start then autoCalculateActive=false; autocalcOperation(); end end function onSave() local objs={} local autol={} local rettab={} local coin if savechanged then if extendCounterCoin then coin=extendCounterCoin.getGUID() end if type(extendCounterObjs).."" == "table" then for _, obj in ipairs(extendCounterObjs) do if obj then table.insert(objs,obj.getGUID()) end end end if type(autoCalculateList).."" == "table" then for _, obj in ipairs(autoCalculateList) do if obj then table.insert(autol,obj.getGUID()) end end end if #objs > 1 then rettab["extendCounterObjs"]=objs end if coin then rettab["extendCounterCoin"]=coin end if #autol > 2 then rettab["autoCalculateList"]=autol end savechanged=false return JSON.encode(rettab) else return self.script_state end end function getAnyVar(tab) return _G[tab[1]] end function setAnyVar(tab) _G[tab[1]]=tab[2] end function onHover(col) if autoCalculateList != nil and showcalcround then local showme={ color=Color(1,1,1), thickness=0.1, rotation=Vector(0,0,0), points={} } local pos=self.getPosition()+Vector(0,0.5,0) local ipos=self.getPosition()-Vector(0,1.5,0) local prevvec=vectorToLocal(pos,self.getPosition(),self.getScale(),self.getRotation()) local list={} i=#autoCalculateList while i > 0 do showme.color=Color(1,1,1):lerp(Color(0,0,1),(#autoCalculateList-i)/(#autoCalculateList-1)) table.insert(list,makecopytab(showme,1)) list[#autoCalculateList-i+1].points[1]=prevvec local obj=autoCalculateList[i] list[#autoCalculateList-i+1].points[2]=vectorToLocal(obj.getPosition(),ipos,self.getScale()*Vector(3,3,3),self.getRotation()) prevvec=list[#autoCalculateList-i+1].points[2] i=i-1 end self.setVectorLines(list) Wait.time(function() self.setVectorLines() end, 3.0) end end function onPickUp(color) if type(extendCounterObjs).."" == "table" then local amount=#extendCounterObjs local selob=Player[color].getSelectedObjects() if selob then if #selob == amount then for i=1, amount do local test = false for x=1, amount do if selob[i] == extendCounterObjs[x] then test=true end end if test then return end end end end for i, obj in ipairs(extendCounterObjs) do if obj then if string.sub(obj.script_code,obj.getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or obj.getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then obj.call("extflash",{nil}) obj.call("updateContextMenu") else local guid=obj.getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end end end end printToAll("broke connection of ".. amount .." counters.") end end function onDrop(color) startChecking() end function startChecking() if autoconnect then preCheck(os.time()+3) end end function preCheck(secs) if os.time() < secs then if not self.resting and checkWait == nil then checkWait=Wait.time(function() preCheck(secs) end,0.1) else checkWait=nil checkConnections() end else checkWait=nil end end function checkConnections() local finallist={self} local bd=self.getBounds() local scale=self.getScale() local x=bd.size.x / 2.0 local rot=self.getRotation() local left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) local right=Vector()-left local cpos=self.getPosition() local tmppos=cpos local test=true while test do local list=findInRadiusBy(tmppos+left,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,list[1]) else test=false end end tmppos=cpos test=true while test do local list=findInRadiusBy(tmppos+right,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 right=Vector(x+(howfaraconn+0.5)*scale.x,-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,1,list[1]) else test=false end end if #finallist <= 1 then return end local coin=extendCounterCoin for i=1,#finallist do if string.sub(finallist[i].script_code,finallist[i].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or finallist[i].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then finallist[i].call("extflash",{finallist}) if coin then finallist[i].call("scriptcoin",{coin,invertcoin,coinzero}) end else local guid=finallist[i].getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end end printToAll("Connected ".. #finallist .." counters.") end function watchDesc() if savedDesc != self.getDescription() then local a,b=readDesc() createButtons(a,b) savedDesc=self.getDescription() end if savedTint != self.getColorTint() then local a,b=readDesc() createButtons(a,b) savedTint=self.getColorTint() end Wait.time(watchDesc,0.5) end function updateContextMenu() self.clearContextMenu() self.addContextMenuItem("extend counter",extendc) if extendCounterObjs != nil then self.addContextMenuItem("clear",function() local a,minus,c=getTotalValue(); if coinzero == -1 then minus=true elseif coinzero == 1 then minus=false elseif coinzero == 2 then minus=not minus end setTotalValue({0,minus}) end) end self.addContextMenuItem("make autocalc",autocalc) savechanged=true end function extendc(col) if col == nil then extendCounterObjs=nil return end extendCounterObjs=Player[col].getSelectedObjects() extendCounterCoin=nil if extendCounterObjs != nil then if #extendCounterObjs <= 1 then extendCounterObjs=nil elseif #extendCounterObjs >= 2 then -- if self != extendCounterObjs[1] then -- printToAll("[ff0000]ERROR:[-]select smallest counter first, and from smallest counter right click menu.") -- return -- end if extendCounterObjs[i].type.."" != "Counter" then local i=1 while i <= #extendCounterObjs do if string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) and extendCounterObjs[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then local typetest=extendCounterObjs[i].type.."" == "Counter" or (extendCounterObjs[i].getVar("whatIAm") == "Counter") if i == 2 then if i == #extendCounterObjs then extendCounterCoin=extendCounterObjs[#extendCounterObjs] extendCounterObjs=nil return end elseif i == #extendCounterObjs and not typetest then log("LinkkingCounters:we assume this is coin (negitve display)") extendCounterCoin=extendCounterObjs[#extendCounterObjs] table.remove(extendCounterObjs) elseif typetest then printToAll("[ff0000]ERROR:[-]Unknown counter (possibly unexpected behaviour).") else table.remove(extendCounterObjs,i) i=i-1 end elseif string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) then printToAll("[ff0000]ERROR:[-]Counters not the same version (Advanced Counter Mark II) (possibly unexpected behaviour).") end i=i+1 end if #extendCounterObjs >= 2 then extendCounterObjs[1].call("scriptext",{extendCounterObjs,1}) end for i=1, #extendCounterObjs do if extendCounterObjs[i] != self then extendCounterObjs[i].call("scriptcoin",{extendCounterCoin,invertcoin,coinzero}) end end end end updateContextMenu() end function autocalc(col) savechanged=true autoCalculateList=nil if col == nil then return end autoCalculateList=Player[col].getSelectedObjects() Player[col].clearSelectedObjects() if autoCalculateList == nil then return end local i=1 while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i != #autoCalculateList then local test=isOperator(autoCalculateList[i].getName()) if not test then test=isOperator(autoCalculateList[i].getDescription()) end if not test then printToAll("[ff0000]ERROR:[-]autocalc: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) else local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,0),0.45) end, i*0.3+0.7) end else if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then log("non Advanced Counter Mark II detected (or too old version). "..i) else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then log("other version of Advanced Counter Mark II detected. "..i) else log("[00ff00]OK:[-]same version of Advanced Counter Mark II detected. "..i) end end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) end i=i+1 end log(autoCalculateList) table.remove(autoCalculateList) -- remove self if #autoCalculateList > 1 and ((#autoCalculateList % 2) == 1) then autoCalculateActive=false autocalcOperation() else printToAll("[ff0000]ERROR:[-] ".. #autoCalculateList .." long list failed (dropped). Select odd number of objects, starting from counter, then finally select counter to display the value (paired number of selected objects).") autoCalculateList=nil end end function autocalcOperation() if autoCalculateList != nil then if not autoCalculateActive then autoCalculateActive=true local i=1 local lastop local mycalc,myminus=0,false while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i == #autoCalculateList then printToAll("[ff0000]ERROR:[-]autocalcOperation: last one cannot be operator.") end local test=isOperator(autoCalculateList[i].getName()) if test then lastop=autoCalculateList[i].getName() else test=isOperator(autoCalculateList[i].getDescription()) if test then lastop=autoCalculateList[i].getDescription() else printToAll("[ff0000]ERROR:[-]autocalcOperation: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end end else local var,minus,index if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" and not autoCalculateList[i].getVar("Supports_getTotalValue") then var=autoCalculateList[i].getValue() minus=var < 0 else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) else var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) end end if i == 1 then mycalc=math.abs(var) myminus=minus else mycalc,myminus=rawCalcOperation(lastop,mycalc,var,myminus,minus) end end i=i+1 end setTotalValue({mycalc,myminus}) autoCalculateActive=false autoCalculateWait=Wait.time(autocalcOperation,1.0) end end end function debugme() log(extendCounterObjs) log(extendCounterCoin) if autoCalculateList != nil then for i, obj in ipairs(autoCalculateList) do local guid=obj.getGUID() local times=#autoCalculateList Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 0) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 1) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 2) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 3) end else log("nil") end local a,b=readDesc() log(a) log(b) end function extflash(tab) if tab[1] == nil then for i=1, 7 do Wait.time(function() self.highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end else for i=1, 7 do Wait.time(function() self.highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end extset(tab) end function extset(tab) extendCounterObjs=tab[1] updateContextMenu() end function scriptext(tab) if #tab[1] >= tab[2] then extendCounterObjs=tab[1] if #tab[1] > tab[2] then if string.sub(tab[1][tab[2]+1].script_code,tab[1][tab[2]+1].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or tab[1][tab[2]+1].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then tab[1][tab[2]+1].call("scriptext",{tab[1],tab[2]+1}) else -- end end updateContextMenu() end end function scriptcoin(coin) extendCounterCoin=coin[1] if #coin > 1 then if coin[2] != nil then invertcoin=coin[2] end if #coin > 2 then if coin[3] != nil then coinzero=coin[3] end end end end function createButtons(buttonlist,whatlist) self.clearButtons() local bgcol=self.getColorTint() local test=(bgcol.r * 0.3 + bgcol.r * 0.3 * (1-bgcol.g) + bgcol.g + bgcol.b * 0.4 > 0.925) local txtcol=test and Color(1,1,1) or Color(0,0,0) local buttcol=test and Color(0.2,0.2,0.2) or Color(0.8,0.8,0.8) local butthov=Color(0.5,0.5,0.5) --[[ self.createButton({ click_function=nil, function_owner=self, label=" ", position=Vector(0,0.2,-0.4-(math.ceil(#buttonlist/2)*0.08-0.08)), scale=Vector(0.1,1,0.1), width=4500, height=800*math.ceil(#buttonlist/2)+200, color={bgcol.r,bgcol.g,bgcol.b}, hover_color={bgcol.r,bgcol.g,bgcol.b}, press_color={bgcol.r,bgcol.g,bgcol.b} })]] local buttonorginpos=Vector(0.32,0.201,-0.41) local frame={ click_function="button", function_owner=self, label=" ", font_size=400, position=buttonorginpos, rotation=Vector(0,180,0), scale=Vector(0.1,1,0.1), width=1000, height=600, color={buttcol.r,buttcol.g,buttcol.b}, hover_color={butthov.r,butthov.g,butthov.b}, press_color={butthov.r,butthov.g,butthov.b}, font_color={txtcol.r,txtcol.g,txtcol.b} } local i=1 local slot=0 local line=0 local halfi=0 local function slothand(slot,lablen) if lablen == 1 then if slot == 0 then return 0 elseif slot == 1 then return -0.21 elseif slot == 2 then return -0.43 elseif slot == 3 then return -0.64 end elseif lablen == 2 then if slot == 0 then return -0.105 elseif slot == 1 then return -0.32 elseif slot == 2 then return -0.535 end elseif lablen == 3 then if slot == 0 then return -0.21 elseif slot == 1 then return -0.43 end elseif lablen == 4 then return -0.32 end end while i <= #buttonlist do local lastone=i == #buttonlist local curra,currb local test=whatlist[i] == "" if test then curra,currb=makecopytab(frame,1),makecopytab(frame,1) else curra=makecopytab(frame,1) end local formatted local formtype=numinter(buttonlist[i],nil,true) if formtype == "1" then formatted=string.format("%d",buttonlist[i]) else formatted=buttonlist[i] end local poslab=(test and "+" or (whatlist[i]))..formatted local neglab="-"..formatted local lablen=math.ceil(string.len(poslab)/4.5) if lablen > 4 then lablen=4; end curra.click_function=curra.click_function..(i-1+halfi)*2 if test then currb.click_function=currb.click_function..(i-1+halfi)*2+1 attachIndex("button",(i-1+halfi)*2) attachIndex("button",(i-1+halfi)*2+1) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=neglab if slot+lablen > 4 then line=line+1; slot=0; end currb.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) currb.width=lablen * currb.width currb.label=poslab self.createButton(curra) self.createButton(currb) else attachIndex("button",(i-1+halfi)*2) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=poslab self.createButton(curra) halfi=halfi-0.5 end i=i+1 end end function dummy() end function attachIndex(click_function, index) -- function to create multiple versions of function local fn_name = click_function .. index _G[fn_name] = function(obj, player_color, alt_click) _G[click_function](obj, player_color, alt_click, index) end return fn_name end function getTotalValue() if extendCounterObjs == nil then if extendCounterCoin == nil then local var=tonumber(self.getValue()) or 0 return var,var < 0,1 else local minus local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end return (minus and -math.abs(tonumber(self.getValue()) or 0) or math.abs(tonumber(self.getValue()) or 0)),minus,1 end else local meCounterIndex local i=1 while i <= #extendCounterObjs do if extendCounterObjs[i] == self then meCounterIndex=i end if extendCounterObjs[i] == nil then log("linked counter operation, counter "..i.." removed.") table.remove(extendCounterObjs,i) i=i-1 end i=i+1 end if #extendCounterObjs <= 1 then printToAll("[ff0000]ERROR:[-]Only one counter left, and started linkked counter operation.") extendCounterObjs=nil updateContextMenu() return getTotalValue() end if meCounterIndex == nil then printToAll("[ff0000]ERROR:[-]did not find index of counter."); return nil,nil,nil end local var=0 i=#extendCounterObjs local minus if extendCounterCoin == nil then minus=false else local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end end while i >= 1 do var=math.abs(tonumber(extendCounterObjs[i].getValue()) or 0) + var * 10000 i=i-1 end return (minus and -var or var),minus,meCounterIndex end end function setTotalValue(tab) local var,minus if type(tab).."" == "table" then if #tab >= 1 then var=tab[1] end if #tab >= 2 then minus=tab[2] end else log("setTotalValue:not a table") end if extendCounterObjs == nil then if minus == nil then minus=var < 0 end if minus and extendCounterCoin == nil then var=math.abs(var) % (minus and 1000 or 10000) elseif extendCounterCoin != nil then var=math.abs(var) % 10000 local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end if extendCounterCoin == nil then self.setValue(minus and -var or var) else self.setValue(var) end else if minus == nil then minus=var < 0 end var=var % math.pow(10000,#extendCounterObjs) if minus and extendCounterCoin == nil then var=math.pow(10000,#extendCounterObjs) - var elseif extendCounterCoin != nil then local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end i=#extendCounterObjs while i >= 1 do extendCounterObjs[i].setValue(math.floor(var/math.pow(10000,i-1)) % 10000) i=i-1 end end end function button(obj, col, alt_click, index) local list=self.getButtons() local var,minus,meCounterIndex=getTotalValue() local currlabel=list[index+1].label local oplett=string.sub(currlabel,1,1) local addable=numinter(string.sub(currlabel,2),0) var,minus=rawCalcOperation(oplett,var,addable * math.pow(10000,meCounterIndex-1),minus,false) setTotalValue({var,minus}) end function wrapCalcOperation(tab) local a,b,c,d,e if type(tab).."" == "table" then if #tab >= 1 then a=tab[1] end if #tab >= 2 then b=tab[2] end if #tab >= 3 then c=tab[3] end if #tab >= 4 then d=tab[4] end if #tab >= 5 then e=tab[5] end for name, item in pairs(tab) do if name == "oplett" then a=item elseif name == "var" then b=item elseif name == "addable" then c=item elseif name == "minus" then d=item elseif name == "addmeg" then e=item end end local var,minus=rawCalcOperation(a,b,c,d,e) return var,minus else log("wrapCalcOperation:not a table") return nil,nil end end function rawCalcOperation(oplett,var,addable,minus,addneg) if minus == nil then if var < 0 then minus=true else minus=false end end if addneg == nil then if addable < 0 then addneg=true else addneg=false end end if isOperator(oplett) then -- if oplett == "+" or oplett == "-" then -- if oplett == "-" and minus then -- oplett="+" -- elseif oplett == "+" and minus then -- oplett="-" -- end -- end else log("rawCalcOperation:Wrong operator") end if minus == addneg then local pah if oplett == "-" and minus then oplett = "+" end pah,var=isOperator(oplett,var,addable) else local pah if oplett == "-" then oplett = "+" elseif oplett == "+" then oplett = "-" end if minus then -- addable positive, var negative pah,var=isOperator(oplett,var,addable) else -- addable negative, var positive pah,var=isOperator(oplett,var,addable) end end if coinzero == 0 then if var < 0 then minus=not minus end elseif coinzero == -1 then if var < 0 then minus=not minus elseif 0 == var then minus=true end elseif coinzero == 1 then if var < 0 then minus=not minus elseif 0 == var then minus=false end elseif coinzero == 2 then if var >= 0 then minus=not minus end elseif coinzero == -2 then if var < 0 then minus=not minus end end return math.abs(var),minus end function isOperator(str,a,b) if type(str).."" == "string" then if string.len(str) == 1 then if type(a).."" == "number" and type(b).."" == "number" then a,b=math.abs(a),math.abs(b) if str == "+" then return true,a+b elseif str == "-" then return true,a-b elseif str == "*" then local pa,pb=a%100000000,b%100000000 local ba,bb=(a-pa)/100000000,(b-pb)/100000000 return true,pa*pb + ((ba*pb)%100000000)*100000000 + ((bb*pa)%100000000)*100000000 elseif str == "/" then return true,math.floor(a/b) elseif str == "&" then local ta,tb=a,b local i=0 local num=0 while ta != 0 and tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == cb and ca == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "|" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == 1 or cb == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "^" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if (ca == 1 and cb == 0) or (ca == 0 and cb == 1) then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "%" then return true,a%b elseif str == "<" then if b == 0 then return true,a end return true,a * math.pow(2,b) elseif str == ">" then if b == 0 then return true,a end return true,math.floor(a / math.pow(2,b)) elseif str == "p" then return true,math.floor(math.pow(a,b)) elseif str == "r" then return true,math.floor(math.pow(a,1.0/b)) end else if str == "+" then return true end if str == "-" then return true end if str == "*" then return true end if str == "/" then return true end if str == "&" then return true end if str == "|" then return true end if str == "^" then return true end if str == "%" then return true end if str == "<" then return true end if str == ">" then return true end if str == "p" then return true end if str == "r" then return true end end else log("isOperator:only one mark accepted ("..str..")") end else log("isOperator:only strings (of one character) accepted") end return false end function numinter(num,default,indentify) if type(num).."" == "number" then return num end if type(num).."" == "string" then local check="0123456789abcdefghijklmnopqrstuvwxyz" local out=nil if string.sub(num,1,1) == "0" then --hex or octaconal if string.sub(num,2,2) == "x" then --hex (base 16) if indentify then return "x" end local i=3 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:hex:not regonized character (".. c ..")"); elseif f >= 1 and f <= 16 then out=(out or 0) * 16 + f - 1 else log("numinter:hex:character out of bounds (".. (f-1) .. ")") end i=i+1 end else --octaconal (base 8) if indentify then return "0" end local i=2 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:octa:not regonized character (".. c ..")"); elseif f >= 1 and f <= 8 then out=(out or 0) * 8 + f - 1 else log("numinter:octa:character out of bounds (".. (f-1) .. "),(".. c ..")") end i=i+1 end end else if indentify then return "1" end out=tonumber(num) end if out == nil then return default else return out end end return default end function readDesc() local buttonlist={} local whatlist={} local desc=self.getDescription() or "" local txtstep=string.find(desc,",",1,true) if txtstep != nil then local prevstep repeat local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),txtstep-1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end prevstep=txtstep txtstep=string.find(desc,",",txtstep+1,true) until txtstep == nil or txtstep == string.len(desc) if textstep == nil then local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),string.len(desc)) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end elseif string.len(desc) > 0 then local poper=string.sub(desc,1,1) local test=isOperator(poper) local num=string.sub(desc,test and 2 or 1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end return buttonlist,whatlist end function makecopytab(tab,depth) local mydepth=depth or 0 if mydepth < 0 then log("this should not have been called. makecopytab") log(tab) return nil end local newtab={} if type(tab).."" == "table" then for x, val in pairs(tab) do if type(x).."" == "number" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then table.insert(newtab,x,Vector(tab[x])) else if mydepth > 0 then table.insert(newtab,x,makecopytab(tab[x],mydepth-1)) else table.insert(newtab,x,{}) end end else table.insert(newtab,x,tab[x]) end elseif type(x).."" == "string" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then newtab[x]=Vector(tab[x]) else if mydepth > 0 then newtab[x]=makecopytab(tab[x],mydepth-1) else newtab[x]={} end end else newtab[x]=tab[x] end end end else return tab end return newtab end function vectorRotate(vec,rot) return vec:rotateOver("z",rot.z):rotateOver("x",rot.x):rotateOver("y",rot.y) end function vectorIRotate(vec,rot) return vec:rotateOver("y",rot.y):rotateOver("x",rot.x):rotateOver("z",rot.z) end function vectorToLocal(target,objvec,objscale,objrot) local copy=Vector(target) copy=copy-(objvec or Vector(0,0,0)) copy=vectorIRotate(copy,(objrot or Vector(0,0,0)):inverse()) local tmp=objscale or Vector(1,1,1) copy=Vector(copy.x / tmp.x,copy.y / tmp.y, copy.z / tmp.z) return copy end function wrapVectorToLocal(tab) return vectorToLocal(tab[1],tab[2],tab[3],tab[4]) end function findInRadiusBy(pos, radius, func, debug) --by MrStump https://steamcommunity.com/sharedfiles/filedetails/?id=752690530&searchtext=lua --if DEBUG then log(" findInRadiusBy(): just called") end local radius = (radius or 1) local objList = Physics.cast({ origin=pos, direction={0,1,0}, type=2, size={radius,radius,radius}, max_distance=0, debug=(debug or false) }) local refinedList = {} for _, obj in ipairs(objList) do if func == nil then if obj.hit_object.type != "Surface" then -- Finaryman Mod table.insert(refinedList, obj.hit_object) end else if func(obj.hit_object) and obj.hit_object.type != "Surface" then --Finaryman Mod table.insert(refinedList, obj.hit_object) end end end return refinedList endLuaScriptState[]XmlUI195Ó¥GUID0636a6NameCounterTransform‰posX€LÀposY`\ºí?posZ,@rotXšp|>rotY ñüQ¿rotZ—ÿr¾scaleX€ÿÿû?scaleY€ÿÿû?scaleZ€ÿÿû?NicknameMoneyDescription 2,5,10,25GMNotesAltLookAngle&xyzColorDiffuse&rs“È?g€—næ?b@�Å?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCountervalueLuaScriptq£function onLoad(str) --In code settings-- invertcoin=false --old negative value is now positive and old positive value is now negative coinzero=-2 --0 > toggle when beond zero, -1 > zero is negative, 1 > zero is positive, 2 > toggle when reached zero, -2 > zero is special autoconnect=true --allow autoconnecting by putting counters next to each other howfaraconn=0.6 --how far autoconnect works (object scale affects this) showcalcround=true --show autocalculation list on hover --End of settings--- savechanged=false local start=false SETTINGS_POS=string.find(self.script_code,"--End of settings---") self.setVar("SETTINGS_POS",SETTINGS_POS) if str != "" and str != nil then local data=JSON.decode(str) for name, info in pairs(data) do if name == "extendCounterObjs" then if type(info).."" == "table" then if #info > 1 then extendCounterObjs={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(extendCounterObjs,obj) end end if #extendCounterObjs < 2 then extendCounterObjs=nil end end end end if name == "extendCounterCoin" then local obj=getObjectFromGUID(info) if obj then extendCounterCoin=obj end end if name == "autoCalculateList" then if type(info).."" == "table" then if #info > 2 then autoCalculateList={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(autoCalculateList,obj) end end if #autoCalculateList < 3 then autoCalculateList=nil else start=true end end end end end end self.setVar("whatIAm","Counter") self.setVar("Supports_getTotalValue",true) self.setVar("whatIAmSpecfically","[finmod]Advanced Counter Mark II") watchDesc() updateContextMenu() if start then autoCalculateActive=false; autocalcOperation(); end end function onSave() local objs={} local autol={} local rettab={} local coin if savechanged then if extendCounterCoin then coin=extendCounterCoin.getGUID() end if type(extendCounterObjs).."" == "table" then for _, obj in ipairs(extendCounterObjs) do if obj then table.insert(objs,obj.getGUID()) end end end if type(autoCalculateList).."" == "table" then for _, obj in ipairs(autoCalculateList) do if obj then table.insert(autol,obj.getGUID()) end end end if #objs > 1 then rettab["extendCounterObjs"]=objs end if coin then rettab["extendCounterCoin"]=coin end if #autol > 2 then rettab["autoCalculateList"]=autol end savechanged=false return JSON.encode(rettab) else return self.script_state end end function getAnyVar(tab) return _G[tab[1]] end function setAnyVar(tab) _G[tab[1]]=tab[2] end function onHover(col) if autoCalculateList != nil and showcalcround then local showme={ color=Color(1,1,1), thickness=0.1, rotation=Vector(0,0,0), points={} } local pos=self.getPosition()+Vector(0,0.5,0) local ipos=self.getPosition()-Vector(0,1.5,0) local prevvec=vectorToLocal(pos,self.getPosition(),self.getScale(),self.getRotation()) local list={} i=#autoCalculateList while i > 0 do showme.color=Color(1,1,1):lerp(Color(0,0,1),(#autoCalculateList-i)/(#autoCalculateList-1)) table.insert(list,makecopytab(showme,1)) list[#autoCalculateList-i+1].points[1]=prevvec local obj=autoCalculateList[i] list[#autoCalculateList-i+1].points[2]=vectorToLocal(obj.getPosition(),ipos,self.getScale()*Vector(3,3,3),self.getRotation()) prevvec=list[#autoCalculateList-i+1].points[2] i=i-1 end self.setVectorLines(list) Wait.time(function() self.setVectorLines() end, 3.0) end end function onPickUp(color) if type(extendCounterObjs).."" == "table" then local amount=#extendCounterObjs local selob=Player[color].getSelectedObjects() if selob then if #selob == amount then for i=1, amount do local test = false for x=1, amount do if selob[i] == extendCounterObjs[x] then test=true end end if test then return end end end end for i, obj in ipairs(extendCounterObjs) do if obj then if string.sub(obj.script_code,obj.getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or obj.getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then obj.call("extflash",{nil}) obj.call("updateContextMenu") else local guid=obj.getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end end end end printToAll("broke connection of ".. amount .." counters.") end end function onDrop(color) startChecking() end function startChecking() if autoconnect then preCheck(os.time()+3) end end function preCheck(secs) if os.time() < secs then if not self.resting and checkWait == nil then checkWait=Wait.time(function() preCheck(secs) end,0.1) else checkWait=nil checkConnections() end else checkWait=nil end end function checkConnections() local finallist={self} local bd=self.getBounds() local scale=self.getScale() local x=bd.size.x / 2.0 local rot=self.getRotation() local left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) local right=Vector()-left local cpos=self.getPosition() local tmppos=cpos local test=true while test do local list=findInRadiusBy(tmppos+left,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,list[1]) else test=false end end tmppos=cpos test=true while test do local list=findInRadiusBy(tmppos+right,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 right=Vector(x+(howfaraconn+0.5)*scale.x,-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,1,list[1]) else test=false end end if #finallist <= 1 then return end local coin=extendCounterCoin for i=1,#finallist do if string.sub(finallist[i].script_code,finallist[i].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or finallist[i].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then finallist[i].call("extflash",{finallist}) if coin then finallist[i].call("scriptcoin",{coin,invertcoin,coinzero}) end else local guid=finallist[i].getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end end printToAll("Connected ".. #finallist .." counters.") end function watchDesc() if savedDesc != self.getDescription() then local a,b=readDesc() createButtons(a,b) savedDesc=self.getDescription() end if savedTint != self.getColorTint() then local a,b=readDesc() createButtons(a,b) savedTint=self.getColorTint() end Wait.time(watchDesc,0.5) end function updateContextMenu() self.clearContextMenu() self.addContextMenuItem("extend counter",extendc) if extendCounterObjs != nil then self.addContextMenuItem("clear",function() local a,minus,c=getTotalValue(); if coinzero == -1 then minus=true elseif coinzero == 1 then minus=false elseif coinzero == 2 then minus=not minus end setTotalValue({0,minus}) end) end self.addContextMenuItem("make autocalc",autocalc) savechanged=true end function extendc(col) if col == nil then extendCounterObjs=nil return end extendCounterObjs=Player[col].getSelectedObjects() extendCounterCoin=nil if extendCounterObjs != nil then if #extendCounterObjs <= 1 then extendCounterObjs=nil elseif #extendCounterObjs >= 2 then -- if self != extendCounterObjs[1] then -- printToAll("[ff0000]ERROR:[-]select smallest counter first, and from smallest counter right click menu.") -- return -- end if extendCounterObjs[i].type.."" != "Counter" then local i=1 while i <= #extendCounterObjs do if string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) and extendCounterObjs[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then local typetest=extendCounterObjs[i].type.."" == "Counter" or (extendCounterObjs[i].getVar("whatIAm") == "Counter") if i == 2 then if i == #extendCounterObjs then extendCounterCoin=extendCounterObjs[#extendCounterObjs] extendCounterObjs=nil return end elseif i == #extendCounterObjs and not typetest then log("LinkkingCounters:we assume this is coin (negitve display)") extendCounterCoin=extendCounterObjs[#extendCounterObjs] table.remove(extendCounterObjs) elseif typetest then printToAll("[ff0000]ERROR:[-]Unknown counter (possibly unexpected behaviour).") else table.remove(extendCounterObjs,i) i=i-1 end elseif string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) then printToAll("[ff0000]ERROR:[-]Counters not the same version (Advanced Counter Mark II) (possibly unexpected behaviour).") end i=i+1 end if #extendCounterObjs >= 2 then extendCounterObjs[1].call("scriptext",{extendCounterObjs,1}) end for i=1, #extendCounterObjs do if extendCounterObjs[i] != self then extendCounterObjs[i].call("scriptcoin",{extendCounterCoin,invertcoin,coinzero}) end end end end updateContextMenu() end function autocalc(col) savechanged=true autoCalculateList=nil if col == nil then return end autoCalculateList=Player[col].getSelectedObjects() Player[col].clearSelectedObjects() if autoCalculateList == nil then return end local i=1 while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i != #autoCalculateList then local test=isOperator(autoCalculateList[i].getName()) if not test then test=isOperator(autoCalculateList[i].getDescription()) end if not test then printToAll("[ff0000]ERROR:[-]autocalc: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) else local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,0),0.45) end, i*0.3+0.7) end else if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then log("non Advanced Counter Mark II detected (or too old version). "..i) else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then log("other version of Advanced Counter Mark II detected. "..i) else log("[00ff00]OK:[-]same version of Advanced Counter Mark II detected. "..i) end end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) end i=i+1 end log(autoCalculateList) table.remove(autoCalculateList) -- remove self if #autoCalculateList > 1 and ((#autoCalculateList % 2) == 1) then autoCalculateActive=false autocalcOperation() else printToAll("[ff0000]ERROR:[-] ".. #autoCalculateList .." long list failed (dropped). Select odd number of objects, starting from counter, then finally select counter to display the value (paired number of selected objects).") autoCalculateList=nil end end function autocalcOperation() if autoCalculateList != nil then if not autoCalculateActive then autoCalculateActive=true local i=1 local lastop local mycalc,myminus=0,false while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i == #autoCalculateList then printToAll("[ff0000]ERROR:[-]autocalcOperation: last one cannot be operator.") end local test=isOperator(autoCalculateList[i].getName()) if test then lastop=autoCalculateList[i].getName() else test=isOperator(autoCalculateList[i].getDescription()) if test then lastop=autoCalculateList[i].getDescription() else printToAll("[ff0000]ERROR:[-]autocalcOperation: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end end else local var,minus,index if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" and not autoCalculateList[i].getVar("Supports_getTotalValue") then var=autoCalculateList[i].getValue() minus=var < 0 else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) else var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) end end if i == 1 then mycalc=math.abs(var) myminus=minus else mycalc,myminus=rawCalcOperation(lastop,mycalc,var,myminus,minus) end end i=i+1 end setTotalValue({mycalc,myminus}) autoCalculateActive=false autoCalculateWait=Wait.time(autocalcOperation,1.0) end end end function debugme() log(extendCounterObjs) log(extendCounterCoin) if autoCalculateList != nil then for i, obj in ipairs(autoCalculateList) do local guid=obj.getGUID() local times=#autoCalculateList Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 0) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 1) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 2) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 3) end else log("nil") end local a,b=readDesc() log(a) log(b) end function extflash(tab) if tab[1] == nil then for i=1, 7 do Wait.time(function() self.highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end else for i=1, 7 do Wait.time(function() self.highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end extset(tab) end function extset(tab) extendCounterObjs=tab[1] updateContextMenu() end function scriptext(tab) if #tab[1] >= tab[2] then extendCounterObjs=tab[1] if #tab[1] > tab[2] then if string.sub(tab[1][tab[2]+1].script_code,tab[1][tab[2]+1].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or tab[1][tab[2]+1].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then tab[1][tab[2]+1].call("scriptext",{tab[1],tab[2]+1}) else -- end end updateContextMenu() end end function scriptcoin(coin) extendCounterCoin=coin[1] if #coin > 1 then if coin[2] != nil then invertcoin=coin[2] end if #coin > 2 then if coin[3] != nil then coinzero=coin[3] end end end end function createButtons(buttonlist,whatlist) self.clearButtons() local bgcol=self.getColorTint() local test=(bgcol.r * 0.3 + bgcol.r * 0.3 * (1-bgcol.g) + bgcol.g + bgcol.b * 0.4 > 0.925) local txtcol=test and Color(1,1,1) or Color(0,0,0) local buttcol=test and Color(0.2,0.2,0.2) or Color(0.8,0.8,0.8) local butthov=Color(0.5,0.5,0.5) --[[ self.createButton({ click_function=nil, function_owner=self, label=" ", position=Vector(0,0.2,-0.4-(math.ceil(#buttonlist/2)*0.08-0.08)), scale=Vector(0.1,1,0.1), width=4500, height=800*math.ceil(#buttonlist/2)+200, color={bgcol.r,bgcol.g,bgcol.b}, hover_color={bgcol.r,bgcol.g,bgcol.b}, press_color={bgcol.r,bgcol.g,bgcol.b} })]] local buttonorginpos=Vector(0.32,0.201,-0.41) local frame={ click_function="button", function_owner=self, label=" ", font_size=400, position=buttonorginpos, rotation=Vector(0,180,0), scale=Vector(0.1,1,0.1), width=1000, height=600, color={buttcol.r,buttcol.g,buttcol.b}, hover_color={butthov.r,butthov.g,butthov.b}, press_color={butthov.r,butthov.g,butthov.b}, font_color={txtcol.r,txtcol.g,txtcol.b} } local i=1 local slot=0 local line=0 local halfi=0 local function slothand(slot,lablen) if lablen == 1 then if slot == 0 then return 0 elseif slot == 1 then return -0.21 elseif slot == 2 then return -0.43 elseif slot == 3 then return -0.64 end elseif lablen == 2 then if slot == 0 then return -0.105 elseif slot == 1 then return -0.32 elseif slot == 2 then return -0.535 end elseif lablen == 3 then if slot == 0 then return -0.21 elseif slot == 1 then return -0.43 end elseif lablen == 4 then return -0.32 end end while i <= #buttonlist do local lastone=i == #buttonlist local curra,currb local test=whatlist[i] == "" if test then curra,currb=makecopytab(frame,1),makecopytab(frame,1) else curra=makecopytab(frame,1) end local formatted local formtype=numinter(buttonlist[i],nil,true) if formtype == "1" then formatted=string.format("%d",buttonlist[i]) else formatted=buttonlist[i] end local poslab=(test and "+" or (whatlist[i]))..formatted local neglab="-"..formatted local lablen=math.ceil(string.len(poslab)/4.5) if lablen > 4 then lablen=4; end curra.click_function=curra.click_function..(i-1+halfi)*2 if test then currb.click_function=currb.click_function..(i-1+halfi)*2+1 attachIndex("button",(i-1+halfi)*2) attachIndex("button",(i-1+halfi)*2+1) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=neglab if slot+lablen > 4 then line=line+1; slot=0; end currb.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) currb.width=lablen * currb.width currb.label=poslab self.createButton(curra) self.createButton(currb) else attachIndex("button",(i-1+halfi)*2) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=poslab self.createButton(curra) halfi=halfi-0.5 end i=i+1 end end function dummy() end function attachIndex(click_function, index) -- function to create multiple versions of function local fn_name = click_function .. index _G[fn_name] = function(obj, player_color, alt_click) _G[click_function](obj, player_color, alt_click, index) end return fn_name end function getTotalValue() if extendCounterObjs == nil then if extendCounterCoin == nil then local var=tonumber(self.getValue()) or 0 return var,var < 0,1 else local minus local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end return (minus and -math.abs(tonumber(self.getValue()) or 0) or math.abs(tonumber(self.getValue()) or 0)),minus,1 end else local meCounterIndex local i=1 while i <= #extendCounterObjs do if extendCounterObjs[i] == self then meCounterIndex=i end if extendCounterObjs[i] == nil then log("linked counter operation, counter "..i.." removed.") table.remove(extendCounterObjs,i) i=i-1 end i=i+1 end if #extendCounterObjs <= 1 then printToAll("[ff0000]ERROR:[-]Only one counter left, and started linkked counter operation.") extendCounterObjs=nil updateContextMenu() return getTotalValue() end if meCounterIndex == nil then printToAll("[ff0000]ERROR:[-]did not find index of counter."); return nil,nil,nil end local var=0 i=#extendCounterObjs local minus if extendCounterCoin == nil then minus=false else local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end end while i >= 1 do var=math.abs(tonumber(extendCounterObjs[i].getValue()) or 0) + var * 10000 i=i-1 end return (minus and -var or var),minus,meCounterIndex end end function setTotalValue(tab) local var,minus if type(tab).."" == "table" then if #tab >= 1 then var=tab[1] end if #tab >= 2 then minus=tab[2] end else log("setTotalValue:not a table") end if extendCounterObjs == nil then if minus == nil then minus=var < 0 end if minus and extendCounterCoin == nil then var=math.abs(var) % (minus and 1000 or 10000) elseif extendCounterCoin != nil then var=math.abs(var) % 10000 local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end if extendCounterCoin == nil then self.setValue(minus and -var or var) else self.setValue(var) end else if minus == nil then minus=var < 0 end var=var % math.pow(10000,#extendCounterObjs) if minus and extendCounterCoin == nil then var=math.pow(10000,#extendCounterObjs) - var elseif extendCounterCoin != nil then local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end i=#extendCounterObjs while i >= 1 do extendCounterObjs[i].setValue(math.floor(var/math.pow(10000,i-1)) % 10000) i=i-1 end end end function button(obj, col, alt_click, index) local list=self.getButtons() local var,minus,meCounterIndex=getTotalValue() local currlabel=list[index+1].label local oplett=string.sub(currlabel,1,1) local addable=numinter(string.sub(currlabel,2),0) var,minus=rawCalcOperation(oplett,var,addable * math.pow(10000,meCounterIndex-1),minus,false) setTotalValue({var,minus}) end function wrapCalcOperation(tab) local a,b,c,d,e if type(tab).."" == "table" then if #tab >= 1 then a=tab[1] end if #tab >= 2 then b=tab[2] end if #tab >= 3 then c=tab[3] end if #tab >= 4 then d=tab[4] end if #tab >= 5 then e=tab[5] end for name, item in pairs(tab) do if name == "oplett" then a=item elseif name == "var" then b=item elseif name == "addable" then c=item elseif name == "minus" then d=item elseif name == "addmeg" then e=item end end local var,minus=rawCalcOperation(a,b,c,d,e) return var,minus else log("wrapCalcOperation:not a table") return nil,nil end end function rawCalcOperation(oplett,var,addable,minus,addneg) if minus == nil then if var < 0 then minus=true else minus=false end end if addneg == nil then if addable < 0 then addneg=true else addneg=false end end if isOperator(oplett) then -- if oplett == "+" or oplett == "-" then -- if oplett == "-" and minus then -- oplett="+" -- elseif oplett == "+" and minus then -- oplett="-" -- end -- end else log("rawCalcOperation:Wrong operator") end if minus == addneg then local pah if oplett == "-" and minus then oplett = "+" end pah,var=isOperator(oplett,var,addable) else local pah if oplett == "-" then oplett = "+" elseif oplett == "+" then oplett = "-" end if minus then -- addable positive, var negative pah,var=isOperator(oplett,var,addable) else -- addable negative, var positive pah,var=isOperator(oplett,var,addable) end end if coinzero == 0 then if var < 0 then minus=not minus end elseif coinzero == -1 then if var < 0 then minus=not minus elseif 0 == var then minus=true end elseif coinzero == 1 then if var < 0 then minus=not minus elseif 0 == var then minus=false end elseif coinzero == 2 then if var >= 0 then minus=not minus end elseif coinzero == -2 then if var < 0 then minus=not minus end end return math.abs(var),minus end function isOperator(str,a,b) if type(str).."" == "string" then if string.len(str) == 1 then if type(a).."" == "number" and type(b).."" == "number" then a,b=math.abs(a),math.abs(b) if str == "+" then return true,a+b elseif str == "-" then return true,a-b elseif str == "*" then local pa,pb=a%100000000,b%100000000 local ba,bb=(a-pa)/100000000,(b-pb)/100000000 return true,pa*pb + ((ba*pb)%100000000)*100000000 + ((bb*pa)%100000000)*100000000 elseif str == "/" then return true,math.floor(a/b) elseif str == "&" then local ta,tb=a,b local i=0 local num=0 while ta != 0 and tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == cb and ca == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "|" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == 1 or cb == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "^" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if (ca == 1 and cb == 0) or (ca == 0 and cb == 1) then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "%" then return true,a%b elseif str == "<" then if b == 0 then return true,a end return true,a * math.pow(2,b) elseif str == ">" then if b == 0 then return true,a end return true,math.floor(a / math.pow(2,b)) elseif str == "p" then return true,math.floor(math.pow(a,b)) elseif str == "r" then return true,math.floor(math.pow(a,1.0/b)) end else if str == "+" then return true end if str == "-" then return true end if str == "*" then return true end if str == "/" then return true end if str == "&" then return true end if str == "|" then return true end if str == "^" then return true end if str == "%" then return true end if str == "<" then return true end if str == ">" then return true end if str == "p" then return true end if str == "r" then return true end end else log("isOperator:only one mark accepted ("..str..")") end else log("isOperator:only strings (of one character) accepted") end return false end function numinter(num,default,indentify) if type(num).."" == "number" then return num end if type(num).."" == "string" then local check="0123456789abcdefghijklmnopqrstuvwxyz" local out=nil if string.sub(num,1,1) == "0" then --hex or octaconal if string.sub(num,2,2) == "x" then --hex (base 16) if indentify then return "x" end local i=3 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:hex:not regonized character (".. c ..")"); elseif f >= 1 and f <= 16 then out=(out or 0) * 16 + f - 1 else log("numinter:hex:character out of bounds (".. (f-1) .. ")") end i=i+1 end else --octaconal (base 8) if indentify then return "0" end local i=2 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:octa:not regonized character (".. c ..")"); elseif f >= 1 and f <= 8 then out=(out or 0) * 8 + f - 1 else log("numinter:octa:character out of bounds (".. (f-1) .. "),(".. c ..")") end i=i+1 end end else if indentify then return "1" end out=tonumber(num) end if out == nil then return default else return out end end return default end function readDesc() local buttonlist={} local whatlist={} local desc=self.getDescription() or "" local txtstep=string.find(desc,",",1,true) if txtstep != nil then local prevstep repeat local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),txtstep-1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end prevstep=txtstep txtstep=string.find(desc,",",txtstep+1,true) until txtstep == nil or txtstep == string.len(desc) if textstep == nil then local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),string.len(desc)) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end elseif string.len(desc) > 0 then local poper=string.sub(desc,1,1) local test=isOperator(poper) local num=string.sub(desc,test and 2 or 1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end return buttonlist,whatlist end function makecopytab(tab,depth) local mydepth=depth or 0 if mydepth < 0 then log("this should not have been called. makecopytab") log(tab) return nil end local newtab={} if type(tab).."" == "table" then for x, val in pairs(tab) do if type(x).."" == "number" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then table.insert(newtab,x,Vector(tab[x])) else if mydepth > 0 then table.insert(newtab,x,makecopytab(tab[x],mydepth-1)) else table.insert(newtab,x,{}) end end else table.insert(newtab,x,tab[x]) end elseif type(x).."" == "string" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then newtab[x]=Vector(tab[x]) else if mydepth > 0 then newtab[x]=makecopytab(tab[x],mydepth-1) else newtab[x]={} end end else newtab[x]=tab[x] end end end else return tab end return newtab end function vectorRotate(vec,rot) return vec:rotateOver("z",rot.z):rotateOver("x",rot.x):rotateOver("y",rot.y) end function vectorIRotate(vec,rot) return vec:rotateOver("y",rot.y):rotateOver("x",rot.x):rotateOver("z",rot.z) end function vectorToLocal(target,objvec,objscale,objrot) local copy=Vector(target) copy=copy-(objvec or Vector(0,0,0)) copy=vectorIRotate(copy,(objrot or Vector(0,0,0)):inverse()) local tmp=objscale or Vector(1,1,1) copy=Vector(copy.x / tmp.x,copy.y / tmp.y, copy.z / tmp.z) return copy end function wrapVectorToLocal(tab) return vectorToLocal(tab[1],tab[2],tab[3],tab[4]) end function findInRadiusBy(pos, radius, func, debug) --by MrStump https://steamcommunity.com/sharedfiles/filedetails/?id=752690530&searchtext=lua --if DEBUG then log(" findInRadiusBy(): just called") end local radius = (radius or 1) local objList = Physics.cast({ origin=pos, direction={0,1,0}, type=2, size={radius,radius,radius}, max_distance=0, debug=(debug or false) }) local refinedList = {} for _, obj in ipairs(objList) do if func == nil then if obj.hit_object.type != "Surface" then -- Finaryman Mod table.insert(refinedList, obj.hit_object) end else if func(obj.hit_object) and obj.hit_object.type != "Surface" then --Finaryman Mod table.insert(refinedList, obj.hit_object) end end end return refinedList endLuaScriptState[]XmlUI196Ó¥GUID3f2ca3NameCounterTransform‰posXÀLÀposY \ºí?posZ%ÀrotXô�¾rotY žüQ¿rotZ€Ð£�¾scaleX€ÿÿû?scaleY€ÿÿû?scaleZ€ÿÿû?NicknameMoneyDescription 2,5,10,25GMNotesAltLookAngle&xyzColorDiffuse&r@bä?g üÿ¿?b¬î?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCountervalueLuaScriptq£function onLoad(str) --In code settings-- invertcoin=false --old negative value is now positive and old positive value is now negative coinzero=-2 --0 > toggle when beond zero, -1 > zero is negative, 1 > zero is positive, 2 > toggle when reached zero, -2 > zero is special autoconnect=true --allow autoconnecting by putting counters next to each other howfaraconn=0.6 --how far autoconnect works (object scale affects this) showcalcround=true --show autocalculation list on hover --End of settings--- savechanged=false local start=false SETTINGS_POS=string.find(self.script_code,"--End of settings---") self.setVar("SETTINGS_POS",SETTINGS_POS) if str != "" and str != nil then local data=JSON.decode(str) for name, info in pairs(data) do if name == "extendCounterObjs" then if type(info).."" == "table" then if #info > 1 then extendCounterObjs={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(extendCounterObjs,obj) end end if #extendCounterObjs < 2 then extendCounterObjs=nil end end end end if name == "extendCounterCoin" then local obj=getObjectFromGUID(info) if obj then extendCounterCoin=obj end end if name == "autoCalculateList" then if type(info).."" == "table" then if #info > 2 then autoCalculateList={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(autoCalculateList,obj) end end if #autoCalculateList < 3 then autoCalculateList=nil else start=true end end end end end end self.setVar("whatIAm","Counter") self.setVar("Supports_getTotalValue",true) self.setVar("whatIAmSpecfically","[finmod]Advanced Counter Mark II") watchDesc() updateContextMenu() if start then autoCalculateActive=false; autocalcOperation(); end end function onSave() local objs={} local autol={} local rettab={} local coin if savechanged then if extendCounterCoin then coin=extendCounterCoin.getGUID() end if type(extendCounterObjs).."" == "table" then for _, obj in ipairs(extendCounterObjs) do if obj then table.insert(objs,obj.getGUID()) end end end if type(autoCalculateList).."" == "table" then for _, obj in ipairs(autoCalculateList) do if obj then table.insert(autol,obj.getGUID()) end end end if #objs > 1 then rettab["extendCounterObjs"]=objs end if coin then rettab["extendCounterCoin"]=coin end if #autol > 2 then rettab["autoCalculateList"]=autol end savechanged=false return JSON.encode(rettab) else return self.script_state end end function getAnyVar(tab) return _G[tab[1]] end function setAnyVar(tab) _G[tab[1]]=tab[2] end function onHover(col) if autoCalculateList != nil and showcalcround then local showme={ color=Color(1,1,1), thickness=0.1, rotation=Vector(0,0,0), points={} } local pos=self.getPosition()+Vector(0,0.5,0) local ipos=self.getPosition()-Vector(0,1.5,0) local prevvec=vectorToLocal(pos,self.getPosition(),self.getScale(),self.getRotation()) local list={} i=#autoCalculateList while i > 0 do showme.color=Color(1,1,1):lerp(Color(0,0,1),(#autoCalculateList-i)/(#autoCalculateList-1)) table.insert(list,makecopytab(showme,1)) list[#autoCalculateList-i+1].points[1]=prevvec local obj=autoCalculateList[i] list[#autoCalculateList-i+1].points[2]=vectorToLocal(obj.getPosition(),ipos,self.getScale()*Vector(3,3,3),self.getRotation()) prevvec=list[#autoCalculateList-i+1].points[2] i=i-1 end self.setVectorLines(list) Wait.time(function() self.setVectorLines() end, 3.0) end end function onPickUp(color) if type(extendCounterObjs).."" == "table" then local amount=#extendCounterObjs local selob=Player[color].getSelectedObjects() if selob then if #selob == amount then for i=1, amount do local test = false for x=1, amount do if selob[i] == extendCounterObjs[x] then test=true end end if test then return end end end end for i, obj in ipairs(extendCounterObjs) do if obj then if string.sub(obj.script_code,obj.getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or obj.getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then obj.call("extflash",{nil}) obj.call("updateContextMenu") else local guid=obj.getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end end end end printToAll("broke connection of ".. amount .." counters.") end end function onDrop(color) startChecking() end function startChecking() if autoconnect then preCheck(os.time()+3) end end function preCheck(secs) if os.time() < secs then if not self.resting and checkWait == nil then checkWait=Wait.time(function() preCheck(secs) end,0.1) else checkWait=nil checkConnections() end else checkWait=nil end end function checkConnections() local finallist={self} local bd=self.getBounds() local scale=self.getScale() local x=bd.size.x / 2.0 local rot=self.getRotation() local left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) local right=Vector()-left local cpos=self.getPosition() local tmppos=cpos local test=true while test do local list=findInRadiusBy(tmppos+left,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,list[1]) else test=false end end tmppos=cpos test=true while test do local list=findInRadiusBy(tmppos+right,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 right=Vector(x+(howfaraconn+0.5)*scale.x,-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,1,list[1]) else test=false end end if #finallist <= 1 then return end local coin=extendCounterCoin for i=1,#finallist do if string.sub(finallist[i].script_code,finallist[i].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or finallist[i].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then finallist[i].call("extflash",{finallist}) if coin then finallist[i].call("scriptcoin",{coin,invertcoin,coinzero}) end else local guid=finallist[i].getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end end printToAll("Connected ".. #finallist .." counters.") end function watchDesc() if savedDesc != self.getDescription() then local a,b=readDesc() createButtons(a,b) savedDesc=self.getDescription() end if savedTint != self.getColorTint() then local a,b=readDesc() createButtons(a,b) savedTint=self.getColorTint() end Wait.time(watchDesc,0.5) end function updateContextMenu() self.clearContextMenu() self.addContextMenuItem("extend counter",extendc) if extendCounterObjs != nil then self.addContextMenuItem("clear",function() local a,minus,c=getTotalValue(); if coinzero == -1 then minus=true elseif coinzero == 1 then minus=false elseif coinzero == 2 then minus=not minus end setTotalValue({0,minus}) end) end self.addContextMenuItem("make autocalc",autocalc) savechanged=true end function extendc(col) if col == nil then extendCounterObjs=nil return end extendCounterObjs=Player[col].getSelectedObjects() extendCounterCoin=nil if extendCounterObjs != nil then if #extendCounterObjs <= 1 then extendCounterObjs=nil elseif #extendCounterObjs >= 2 then -- if self != extendCounterObjs[1] then -- printToAll("[ff0000]ERROR:[-]select smallest counter first, and from smallest counter right click menu.") -- return -- end if extendCounterObjs[i].type.."" != "Counter" then local i=1 while i <= #extendCounterObjs do if string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) and extendCounterObjs[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then local typetest=extendCounterObjs[i].type.."" == "Counter" or (extendCounterObjs[i].getVar("whatIAm") == "Counter") if i == 2 then if i == #extendCounterObjs then extendCounterCoin=extendCounterObjs[#extendCounterObjs] extendCounterObjs=nil return end elseif i == #extendCounterObjs and not typetest then log("LinkkingCounters:we assume this is coin (negitve display)") extendCounterCoin=extendCounterObjs[#extendCounterObjs] table.remove(extendCounterObjs) elseif typetest then printToAll("[ff0000]ERROR:[-]Unknown counter (possibly unexpected behaviour).") else table.remove(extendCounterObjs,i) i=i-1 end elseif string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) then printToAll("[ff0000]ERROR:[-]Counters not the same version (Advanced Counter Mark II) (possibly unexpected behaviour).") end i=i+1 end if #extendCounterObjs >= 2 then extendCounterObjs[1].call("scriptext",{extendCounterObjs,1}) end for i=1, #extendCounterObjs do if extendCounterObjs[i] != self then extendCounterObjs[i].call("scriptcoin",{extendCounterCoin,invertcoin,coinzero}) end end end end updateContextMenu() end function autocalc(col) savechanged=true autoCalculateList=nil if col == nil then return end autoCalculateList=Player[col].getSelectedObjects() Player[col].clearSelectedObjects() if autoCalculateList == nil then return end local i=1 while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i != #autoCalculateList then local test=isOperator(autoCalculateList[i].getName()) if not test then test=isOperator(autoCalculateList[i].getDescription()) end if not test then printToAll("[ff0000]ERROR:[-]autocalc: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) else local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,0),0.45) end, i*0.3+0.7) end else if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then log("non Advanced Counter Mark II detected (or too old version). "..i) else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then log("other version of Advanced Counter Mark II detected. "..i) else log("[00ff00]OK:[-]same version of Advanced Counter Mark II detected. "..i) end end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) end i=i+1 end log(autoCalculateList) table.remove(autoCalculateList) -- remove self if #autoCalculateList > 1 and ((#autoCalculateList % 2) == 1) then autoCalculateActive=false autocalcOperation() else printToAll("[ff0000]ERROR:[-] ".. #autoCalculateList .." long list failed (dropped). Select odd number of objects, starting from counter, then finally select counter to display the value (paired number of selected objects).") autoCalculateList=nil end end function autocalcOperation() if autoCalculateList != nil then if not autoCalculateActive then autoCalculateActive=true local i=1 local lastop local mycalc,myminus=0,false while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i == #autoCalculateList then printToAll("[ff0000]ERROR:[-]autocalcOperation: last one cannot be operator.") end local test=isOperator(autoCalculateList[i].getName()) if test then lastop=autoCalculateList[i].getName() else test=isOperator(autoCalculateList[i].getDescription()) if test then lastop=autoCalculateList[i].getDescription() else printToAll("[ff0000]ERROR:[-]autocalcOperation: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end end else local var,minus,index if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" and not autoCalculateList[i].getVar("Supports_getTotalValue") then var=autoCalculateList[i].getValue() minus=var < 0 else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) else var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) end end if i == 1 then mycalc=math.abs(var) myminus=minus else mycalc,myminus=rawCalcOperation(lastop,mycalc,var,myminus,minus) end end i=i+1 end setTotalValue({mycalc,myminus}) autoCalculateActive=false autoCalculateWait=Wait.time(autocalcOperation,1.0) end end end function debugme() log(extendCounterObjs) log(extendCounterCoin) if autoCalculateList != nil then for i, obj in ipairs(autoCalculateList) do local guid=obj.getGUID() local times=#autoCalculateList Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 0) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 1) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 2) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 3) end else log("nil") end local a,b=readDesc() log(a) log(b) end function extflash(tab) if tab[1] == nil then for i=1, 7 do Wait.time(function() self.highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end else for i=1, 7 do Wait.time(function() self.highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end extset(tab) end function extset(tab) extendCounterObjs=tab[1] updateContextMenu() end function scriptext(tab) if #tab[1] >= tab[2] then extendCounterObjs=tab[1] if #tab[1] > tab[2] then if string.sub(tab[1][tab[2]+1].script_code,tab[1][tab[2]+1].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or tab[1][tab[2]+1].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then tab[1][tab[2]+1].call("scriptext",{tab[1],tab[2]+1}) else -- end end updateContextMenu() end end function scriptcoin(coin) extendCounterCoin=coin[1] if #coin > 1 then if coin[2] != nil then invertcoin=coin[2] end if #coin > 2 then if coin[3] != nil then coinzero=coin[3] end end end end function createButtons(buttonlist,whatlist) self.clearButtons() local bgcol=self.getColorTint() local test=(bgcol.r * 0.3 + bgcol.r * 0.3 * (1-bgcol.g) + bgcol.g + bgcol.b * 0.4 > 0.925) local txtcol=test and Color(1,1,1) or Color(0,0,0) local buttcol=test and Color(0.2,0.2,0.2) or Color(0.8,0.8,0.8) local butthov=Color(0.5,0.5,0.5) --[[ self.createButton({ click_function=nil, function_owner=self, label=" ", position=Vector(0,0.2,-0.4-(math.ceil(#buttonlist/2)*0.08-0.08)), scale=Vector(0.1,1,0.1), width=4500, height=800*math.ceil(#buttonlist/2)+200, color={bgcol.r,bgcol.g,bgcol.b}, hover_color={bgcol.r,bgcol.g,bgcol.b}, press_color={bgcol.r,bgcol.g,bgcol.b} })]] local buttonorginpos=Vector(0.32,0.201,-0.41) local frame={ click_function="button", function_owner=self, label=" ", font_size=400, position=buttonorginpos, rotation=Vector(0,180,0), scale=Vector(0.1,1,0.1), width=1000, height=600, color={buttcol.r,buttcol.g,buttcol.b}, hover_color={butthov.r,butthov.g,butthov.b}, press_color={butthov.r,butthov.g,butthov.b}, font_color={txtcol.r,txtcol.g,txtcol.b} } local i=1 local slot=0 local line=0 local halfi=0 local function slothand(slot,lablen) if lablen == 1 then if slot == 0 then return 0 elseif slot == 1 then return -0.21 elseif slot == 2 then return -0.43 elseif slot == 3 then return -0.64 end elseif lablen == 2 then if slot == 0 then return -0.105 elseif slot == 1 then return -0.32 elseif slot == 2 then return -0.535 end elseif lablen == 3 then if slot == 0 then return -0.21 elseif slot == 1 then return -0.43 end elseif lablen == 4 then return -0.32 end end while i <= #buttonlist do local lastone=i == #buttonlist local curra,currb local test=whatlist[i] == "" if test then curra,currb=makecopytab(frame,1),makecopytab(frame,1) else curra=makecopytab(frame,1) end local formatted local formtype=numinter(buttonlist[i],nil,true) if formtype == "1" then formatted=string.format("%d",buttonlist[i]) else formatted=buttonlist[i] end local poslab=(test and "+" or (whatlist[i]))..formatted local neglab="-"..formatted local lablen=math.ceil(string.len(poslab)/4.5) if lablen > 4 then lablen=4; end curra.click_function=curra.click_function..(i-1+halfi)*2 if test then currb.click_function=currb.click_function..(i-1+halfi)*2+1 attachIndex("button",(i-1+halfi)*2) attachIndex("button",(i-1+halfi)*2+1) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=neglab if slot+lablen > 4 then line=line+1; slot=0; end currb.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) currb.width=lablen * currb.width currb.label=poslab self.createButton(curra) self.createButton(currb) else attachIndex("button",(i-1+halfi)*2) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=poslab self.createButton(curra) halfi=halfi-0.5 end i=i+1 end end function dummy() end function attachIndex(click_function, index) -- function to create multiple versions of function local fn_name = click_function .. index _G[fn_name] = function(obj, player_color, alt_click) _G[click_function](obj, player_color, alt_click, index) end return fn_name end function getTotalValue() if extendCounterObjs == nil then if extendCounterCoin == nil then local var=tonumber(self.getValue()) or 0 return var,var < 0,1 else local minus local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end return (minus and -math.abs(tonumber(self.getValue()) or 0) or math.abs(tonumber(self.getValue()) or 0)),minus,1 end else local meCounterIndex local i=1 while i <= #extendCounterObjs do if extendCounterObjs[i] == self then meCounterIndex=i end if extendCounterObjs[i] == nil then log("linked counter operation, counter "..i.." removed.") table.remove(extendCounterObjs,i) i=i-1 end i=i+1 end if #extendCounterObjs <= 1 then printToAll("[ff0000]ERROR:[-]Only one counter left, and started linkked counter operation.") extendCounterObjs=nil updateContextMenu() return getTotalValue() end if meCounterIndex == nil then printToAll("[ff0000]ERROR:[-]did not find index of counter."); return nil,nil,nil end local var=0 i=#extendCounterObjs local minus if extendCounterCoin == nil then minus=false else local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end end while i >= 1 do var=math.abs(tonumber(extendCounterObjs[i].getValue()) or 0) + var * 10000 i=i-1 end return (minus and -var or var),minus,meCounterIndex end end function setTotalValue(tab) local var,minus if type(tab).."" == "table" then if #tab >= 1 then var=tab[1] end if #tab >= 2 then minus=tab[2] end else log("setTotalValue:not a table") end if extendCounterObjs == nil then if minus == nil then minus=var < 0 end if minus and extendCounterCoin == nil then var=math.abs(var) % (minus and 1000 or 10000) elseif extendCounterCoin != nil then var=math.abs(var) % 10000 local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end if extendCounterCoin == nil then self.setValue(minus and -var or var) else self.setValue(var) end else if minus == nil then minus=var < 0 end var=var % math.pow(10000,#extendCounterObjs) if minus and extendCounterCoin == nil then var=math.pow(10000,#extendCounterObjs) - var elseif extendCounterCoin != nil then local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end i=#extendCounterObjs while i >= 1 do extendCounterObjs[i].setValue(math.floor(var/math.pow(10000,i-1)) % 10000) i=i-1 end end end function button(obj, col, alt_click, index) local list=self.getButtons() local var,minus,meCounterIndex=getTotalValue() local currlabel=list[index+1].label local oplett=string.sub(currlabel,1,1) local addable=numinter(string.sub(currlabel,2),0) var,minus=rawCalcOperation(oplett,var,addable * math.pow(10000,meCounterIndex-1),minus,false) setTotalValue({var,minus}) end function wrapCalcOperation(tab) local a,b,c,d,e if type(tab).."" == "table" then if #tab >= 1 then a=tab[1] end if #tab >= 2 then b=tab[2] end if #tab >= 3 then c=tab[3] end if #tab >= 4 then d=tab[4] end if #tab >= 5 then e=tab[5] end for name, item in pairs(tab) do if name == "oplett" then a=item elseif name == "var" then b=item elseif name == "addable" then c=item elseif name == "minus" then d=item elseif name == "addmeg" then e=item end end local var,minus=rawCalcOperation(a,b,c,d,e) return var,minus else log("wrapCalcOperation:not a table") return nil,nil end end function rawCalcOperation(oplett,var,addable,minus,addneg) if minus == nil then if var < 0 then minus=true else minus=false end end if addneg == nil then if addable < 0 then addneg=true else addneg=false end end if isOperator(oplett) then -- if oplett == "+" or oplett == "-" then -- if oplett == "-" and minus then -- oplett="+" -- elseif oplett == "+" and minus then -- oplett="-" -- end -- end else log("rawCalcOperation:Wrong operator") end if minus == addneg then local pah if oplett == "-" and minus then oplett = "+" end pah,var=isOperator(oplett,var,addable) else local pah if oplett == "-" then oplett = "+" elseif oplett == "+" then oplett = "-" end if minus then -- addable positive, var negative pah,var=isOperator(oplett,var,addable) else -- addable negative, var positive pah,var=isOperator(oplett,var,addable) end end if coinzero == 0 then if var < 0 then minus=not minus end elseif coinzero == -1 then if var < 0 then minus=not minus elseif 0 == var then minus=true end elseif coinzero == 1 then if var < 0 then minus=not minus elseif 0 == var then minus=false end elseif coinzero == 2 then if var >= 0 then minus=not minus end elseif coinzero == -2 then if var < 0 then minus=not minus end end return math.abs(var),minus end function isOperator(str,a,b) if type(str).."" == "string" then if string.len(str) == 1 then if type(a).."" == "number" and type(b).."" == "number" then a,b=math.abs(a),math.abs(b) if str == "+" then return true,a+b elseif str == "-" then return true,a-b elseif str == "*" then local pa,pb=a%100000000,b%100000000 local ba,bb=(a-pa)/100000000,(b-pb)/100000000 return true,pa*pb + ((ba*pb)%100000000)*100000000 + ((bb*pa)%100000000)*100000000 elseif str == "/" then return true,math.floor(a/b) elseif str == "&" then local ta,tb=a,b local i=0 local num=0 while ta != 0 and tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == cb and ca == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "|" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == 1 or cb == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "^" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if (ca == 1 and cb == 0) or (ca == 0 and cb == 1) then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "%" then return true,a%b elseif str == "<" then if b == 0 then return true,a end return true,a * math.pow(2,b) elseif str == ">" then if b == 0 then return true,a end return true,math.floor(a / math.pow(2,b)) elseif str == "p" then return true,math.floor(math.pow(a,b)) elseif str == "r" then return true,math.floor(math.pow(a,1.0/b)) end else if str == "+" then return true end if str == "-" then return true end if str == "*" then return true end if str == "/" then return true end if str == "&" then return true end if str == "|" then return true end if str == "^" then return true end if str == "%" then return true end if str == "<" then return true end if str == ">" then return true end if str == "p" then return true end if str == "r" then return true end end else log("isOperator:only one mark accepted ("..str..")") end else log("isOperator:only strings (of one character) accepted") end return false end function numinter(num,default,indentify) if type(num).."" == "number" then return num end if type(num).."" == "string" then local check="0123456789abcdefghijklmnopqrstuvwxyz" local out=nil if string.sub(num,1,1) == "0" then --hex or octaconal if string.sub(num,2,2) == "x" then --hex (base 16) if indentify then return "x" end local i=3 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:hex:not regonized character (".. c ..")"); elseif f >= 1 and f <= 16 then out=(out or 0) * 16 + f - 1 else log("numinter:hex:character out of bounds (".. (f-1) .. ")") end i=i+1 end else --octaconal (base 8) if indentify then return "0" end local i=2 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:octa:not regonized character (".. c ..")"); elseif f >= 1 and f <= 8 then out=(out or 0) * 8 + f - 1 else log("numinter:octa:character out of bounds (".. (f-1) .. "),(".. c ..")") end i=i+1 end end else if indentify then return "1" end out=tonumber(num) end if out == nil then return default else return out end end return default end function readDesc() local buttonlist={} local whatlist={} local desc=self.getDescription() or "" local txtstep=string.find(desc,",",1,true) if txtstep != nil then local prevstep repeat local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),txtstep-1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end prevstep=txtstep txtstep=string.find(desc,",",txtstep+1,true) until txtstep == nil or txtstep == string.len(desc) if textstep == nil then local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),string.len(desc)) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end elseif string.len(desc) > 0 then local poper=string.sub(desc,1,1) local test=isOperator(poper) local num=string.sub(desc,test and 2 or 1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end return buttonlist,whatlist end function makecopytab(tab,depth) local mydepth=depth or 0 if mydepth < 0 then log("this should not have been called. makecopytab") log(tab) return nil end local newtab={} if type(tab).."" == "table" then for x, val in pairs(tab) do if type(x).."" == "number" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then table.insert(newtab,x,Vector(tab[x])) else if mydepth > 0 then table.insert(newtab,x,makecopytab(tab[x],mydepth-1)) else table.insert(newtab,x,{}) end end else table.insert(newtab,x,tab[x]) end elseif type(x).."" == "string" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then newtab[x]=Vector(tab[x]) else if mydepth > 0 then newtab[x]=makecopytab(tab[x],mydepth-1) else newtab[x]={} end end else newtab[x]=tab[x] end end end else return tab end return newtab end function vectorRotate(vec,rot) return vec:rotateOver("z",rot.z):rotateOver("x",rot.x):rotateOver("y",rot.y) end function vectorIRotate(vec,rot) return vec:rotateOver("y",rot.y):rotateOver("x",rot.x):rotateOver("z",rot.z) end function vectorToLocal(target,objvec,objscale,objrot) local copy=Vector(target) copy=copy-(objvec or Vector(0,0,0)) copy=vectorIRotate(copy,(objrot or Vector(0,0,0)):inverse()) local tmp=objscale or Vector(1,1,1) copy=Vector(copy.x / tmp.x,copy.y / tmp.y, copy.z / tmp.z) return copy end function wrapVectorToLocal(tab) return vectorToLocal(tab[1],tab[2],tab[3],tab[4]) end function findInRadiusBy(pos, radius, func, debug) --by MrStump https://steamcommunity.com/sharedfiles/filedetails/?id=752690530&searchtext=lua --if DEBUG then log(" findInRadiusBy(): just called") end local radius = (radius or 1) local objList = Physics.cast({ origin=pos, direction={0,1,0}, type=2, size={radius,radius,radius}, max_distance=0, debug=(debug or false) }) local refinedList = {} for _, obj in ipairs(objList) do if func == nil then if obj.hit_object.type != "Surface" then -- Finaryman Mod table.insert(refinedList, obj.hit_object) end else if func(obj.hit_object) and obj.hit_object.type != "Surface" then --Finaryman Mod table.insert(refinedList, obj.hit_object) end end end return refinedList endLuaScriptState[]XmlUI197Ó¥GUID0ca435NameCounterTransform‰posX ÀLÀposY\ºí?posZ@@ÀrotX™DÁ>rotY@bqP¿rotZ@¶…¥>scaleX€ÿÿû?scaleY€ÿÿû?scaleZ€ÿÿû?NicknameMoneyDescription 2,5,10,25GMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCountervalueLuaScriptq£function onLoad(str) --In code settings-- invertcoin=false --old negative value is now positive and old positive value is now negative coinzero=-2 --0 > toggle when beond zero, -1 > zero is negative, 1 > zero is positive, 2 > toggle when reached zero, -2 > zero is special autoconnect=true --allow autoconnecting by putting counters next to each other howfaraconn=0.6 --how far autoconnect works (object scale affects this) showcalcround=true --show autocalculation list on hover --End of settings--- savechanged=false local start=false SETTINGS_POS=string.find(self.script_code,"--End of settings---") self.setVar("SETTINGS_POS",SETTINGS_POS) if str != "" and str != nil then local data=JSON.decode(str) for name, info in pairs(data) do if name == "extendCounterObjs" then if type(info).."" == "table" then if #info > 1 then extendCounterObjs={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(extendCounterObjs,obj) end end if #extendCounterObjs < 2 then extendCounterObjs=nil end end end end if name == "extendCounterCoin" then local obj=getObjectFromGUID(info) if obj then extendCounterCoin=obj end end if name == "autoCalculateList" then if type(info).."" == "table" then if #info > 2 then autoCalculateList={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(autoCalculateList,obj) end end if #autoCalculateList < 3 then autoCalculateList=nil else start=true end end end end end end self.setVar("whatIAm","Counter") self.setVar("Supports_getTotalValue",true) self.setVar("whatIAmSpecfically","[finmod]Advanced Counter Mark II") watchDesc() updateContextMenu() if start then autoCalculateActive=false; autocalcOperation(); end end function onSave() local objs={} local autol={} local rettab={} local coin if savechanged then if extendCounterCoin then coin=extendCounterCoin.getGUID() end if type(extendCounterObjs).."" == "table" then for _, obj in ipairs(extendCounterObjs) do if obj then table.insert(objs,obj.getGUID()) end end end if type(autoCalculateList).."" == "table" then for _, obj in ipairs(autoCalculateList) do if obj then table.insert(autol,obj.getGUID()) end end end if #objs > 1 then rettab["extendCounterObjs"]=objs end if coin then rettab["extendCounterCoin"]=coin end if #autol > 2 then rettab["autoCalculateList"]=autol end savechanged=false return JSON.encode(rettab) else return self.script_state end end function getAnyVar(tab) return _G[tab[1]] end function setAnyVar(tab) _G[tab[1]]=tab[2] end function onHover(col) if autoCalculateList != nil and showcalcround then local showme={ color=Color(1,1,1), thickness=0.1, rotation=Vector(0,0,0), points={} } local pos=self.getPosition()+Vector(0,0.5,0) local ipos=self.getPosition()-Vector(0,1.5,0) local prevvec=vectorToLocal(pos,self.getPosition(),self.getScale(),self.getRotation()) local list={} i=#autoCalculateList while i > 0 do showme.color=Color(1,1,1):lerp(Color(0,0,1),(#autoCalculateList-i)/(#autoCalculateList-1)) table.insert(list,makecopytab(showme,1)) list[#autoCalculateList-i+1].points[1]=prevvec local obj=autoCalculateList[i] list[#autoCalculateList-i+1].points[2]=vectorToLocal(obj.getPosition(),ipos,self.getScale()*Vector(3,3,3),self.getRotation()) prevvec=list[#autoCalculateList-i+1].points[2] i=i-1 end self.setVectorLines(list) Wait.time(function() self.setVectorLines() end, 3.0) end end function onPickUp(color) if type(extendCounterObjs).."" == "table" then local amount=#extendCounterObjs local selob=Player[color].getSelectedObjects() if selob then if #selob == amount then for i=1, amount do local test = false for x=1, amount do if selob[i] == extendCounterObjs[x] then test=true end end if test then return end end end end for i, obj in ipairs(extendCounterObjs) do if obj then if string.sub(obj.script_code,obj.getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or obj.getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then obj.call("extflash",{nil}) obj.call("updateContextMenu") else local guid=obj.getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end end end end printToAll("broke connection of ".. amount .." counters.") end end function onDrop(color) startChecking() end function startChecking() if autoconnect then preCheck(os.time()+3) end end function preCheck(secs) if os.time() < secs then if not self.resting and checkWait == nil then checkWait=Wait.time(function() preCheck(secs) end,0.1) else checkWait=nil checkConnections() end else checkWait=nil end end function checkConnections() local finallist={self} local bd=self.getBounds() local scale=self.getScale() local x=bd.size.x / 2.0 local rot=self.getRotation() local left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) local right=Vector()-left local cpos=self.getPosition() local tmppos=cpos local test=true while test do local list=findInRadiusBy(tmppos+left,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,list[1]) else test=false end end tmppos=cpos test=true while test do local list=findInRadiusBy(tmppos+right,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 right=Vector(x+(howfaraconn+0.5)*scale.x,-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,1,list[1]) else test=false end end if #finallist <= 1 then return end local coin=extendCounterCoin for i=1,#finallist do if string.sub(finallist[i].script_code,finallist[i].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or finallist[i].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then finallist[i].call("extflash",{finallist}) if coin then finallist[i].call("scriptcoin",{coin,invertcoin,coinzero}) end else local guid=finallist[i].getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end end printToAll("Connected ".. #finallist .." counters.") end function watchDesc() if savedDesc != self.getDescription() then local a,b=readDesc() createButtons(a,b) savedDesc=self.getDescription() end if savedTint != self.getColorTint() then local a,b=readDesc() createButtons(a,b) savedTint=self.getColorTint() end Wait.time(watchDesc,0.5) end function updateContextMenu() self.clearContextMenu() self.addContextMenuItem("extend counter",extendc) if extendCounterObjs != nil then self.addContextMenuItem("clear",function() local a,minus,c=getTotalValue(); if coinzero == -1 then minus=true elseif coinzero == 1 then minus=false elseif coinzero == 2 then minus=not minus end setTotalValue({0,minus}) end) end self.addContextMenuItem("make autocalc",autocalc) savechanged=true end function extendc(col) if col == nil then extendCounterObjs=nil return end extendCounterObjs=Player[col].getSelectedObjects() extendCounterCoin=nil if extendCounterObjs != nil then if #extendCounterObjs <= 1 then extendCounterObjs=nil elseif #extendCounterObjs >= 2 then -- if self != extendCounterObjs[1] then -- printToAll("[ff0000]ERROR:[-]select smallest counter first, and from smallest counter right click menu.") -- return -- end if extendCounterObjs[i].type.."" != "Counter" then local i=1 while i <= #extendCounterObjs do if string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) and extendCounterObjs[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then local typetest=extendCounterObjs[i].type.."" == "Counter" or (extendCounterObjs[i].getVar("whatIAm") == "Counter") if i == 2 then if i == #extendCounterObjs then extendCounterCoin=extendCounterObjs[#extendCounterObjs] extendCounterObjs=nil return end elseif i == #extendCounterObjs and not typetest then log("LinkkingCounters:we assume this is coin (negitve display)") extendCounterCoin=extendCounterObjs[#extendCounterObjs] table.remove(extendCounterObjs) elseif typetest then printToAll("[ff0000]ERROR:[-]Unknown counter (possibly unexpected behaviour).") else table.remove(extendCounterObjs,i) i=i-1 end elseif string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) then printToAll("[ff0000]ERROR:[-]Counters not the same version (Advanced Counter Mark II) (possibly unexpected behaviour).") end i=i+1 end if #extendCounterObjs >= 2 then extendCounterObjs[1].call("scriptext",{extendCounterObjs,1}) end for i=1, #extendCounterObjs do if extendCounterObjs[i] != self then extendCounterObjs[i].call("scriptcoin",{extendCounterCoin,invertcoin,coinzero}) end end end end updateContextMenu() end function autocalc(col) savechanged=true autoCalculateList=nil if col == nil then return end autoCalculateList=Player[col].getSelectedObjects() Player[col].clearSelectedObjects() if autoCalculateList == nil then return end local i=1 while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i != #autoCalculateList then local test=isOperator(autoCalculateList[i].getName()) if not test then test=isOperator(autoCalculateList[i].getDescription()) end if not test then printToAll("[ff0000]ERROR:[-]autocalc: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) else local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,0),0.45) end, i*0.3+0.7) end else if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then log("non Advanced Counter Mark II detected (or too old version). "..i) else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then log("other version of Advanced Counter Mark II detected. "..i) else log("[00ff00]OK:[-]same version of Advanced Counter Mark II detected. "..i) end end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) end i=i+1 end log(autoCalculateList) table.remove(autoCalculateList) -- remove self if #autoCalculateList > 1 and ((#autoCalculateList % 2) == 1) then autoCalculateActive=false autocalcOperation() else printToAll("[ff0000]ERROR:[-] ".. #autoCalculateList .." long list failed (dropped). Select odd number of objects, starting from counter, then finally select counter to display the value (paired number of selected objects).") autoCalculateList=nil end end function autocalcOperation() if autoCalculateList != nil then if not autoCalculateActive then autoCalculateActive=true local i=1 local lastop local mycalc,myminus=0,false while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i == #autoCalculateList then printToAll("[ff0000]ERROR:[-]autocalcOperation: last one cannot be operator.") end local test=isOperator(autoCalculateList[i].getName()) if test then lastop=autoCalculateList[i].getName() else test=isOperator(autoCalculateList[i].getDescription()) if test then lastop=autoCalculateList[i].getDescription() else printToAll("[ff0000]ERROR:[-]autocalcOperation: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end end else local var,minus,index if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" and not autoCalculateList[i].getVar("Supports_getTotalValue") then var=autoCalculateList[i].getValue() minus=var < 0 else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) else var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) end end if i == 1 then mycalc=math.abs(var) myminus=minus else mycalc,myminus=rawCalcOperation(lastop,mycalc,var,myminus,minus) end end i=i+1 end setTotalValue({mycalc,myminus}) autoCalculateActive=false autoCalculateWait=Wait.time(autocalcOperation,1.0) end end end function debugme() log(extendCounterObjs) log(extendCounterCoin) if autoCalculateList != nil then for i, obj in ipairs(autoCalculateList) do local guid=obj.getGUID() local times=#autoCalculateList Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 0) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 1) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 2) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 3) end else log("nil") end local a,b=readDesc() log(a) log(b) end function extflash(tab) if tab[1] == nil then for i=1, 7 do Wait.time(function() self.highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end else for i=1, 7 do Wait.time(function() self.highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end extset(tab) end function extset(tab) extendCounterObjs=tab[1] updateContextMenu() end function scriptext(tab) if #tab[1] >= tab[2] then extendCounterObjs=tab[1] if #tab[1] > tab[2] then if string.sub(tab[1][tab[2]+1].script_code,tab[1][tab[2]+1].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or tab[1][tab[2]+1].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then tab[1][tab[2]+1].call("scriptext",{tab[1],tab[2]+1}) else -- end end updateContextMenu() end end function scriptcoin(coin) extendCounterCoin=coin[1] if #coin > 1 then if coin[2] != nil then invertcoin=coin[2] end if #coin > 2 then if coin[3] != nil then coinzero=coin[3] end end end end function createButtons(buttonlist,whatlist) self.clearButtons() local bgcol=self.getColorTint() local test=(bgcol.r * 0.3 + bgcol.r * 0.3 * (1-bgcol.g) + bgcol.g + bgcol.b * 0.4 > 0.925) local txtcol=test and Color(1,1,1) or Color(0,0,0) local buttcol=test and Color(0.2,0.2,0.2) or Color(0.8,0.8,0.8) local butthov=Color(0.5,0.5,0.5) --[[ self.createButton({ click_function=nil, function_owner=self, label=" ", position=Vector(0,0.2,-0.4-(math.ceil(#buttonlist/2)*0.08-0.08)), scale=Vector(0.1,1,0.1), width=4500, height=800*math.ceil(#buttonlist/2)+200, color={bgcol.r,bgcol.g,bgcol.b}, hover_color={bgcol.r,bgcol.g,bgcol.b}, press_color={bgcol.r,bgcol.g,bgcol.b} })]] local buttonorginpos=Vector(0.32,0.201,-0.41) local frame={ click_function="button", function_owner=self, label=" ", font_size=400, position=buttonorginpos, rotation=Vector(0,180,0), scale=Vector(0.1,1,0.1), width=1000, height=600, color={buttcol.r,buttcol.g,buttcol.b}, hover_color={butthov.r,butthov.g,butthov.b}, press_color={butthov.r,butthov.g,butthov.b}, font_color={txtcol.r,txtcol.g,txtcol.b} } local i=1 local slot=0 local line=0 local halfi=0 local function slothand(slot,lablen) if lablen == 1 then if slot == 0 then return 0 elseif slot == 1 then return -0.21 elseif slot == 2 then return -0.43 elseif slot == 3 then return -0.64 end elseif lablen == 2 then if slot == 0 then return -0.105 elseif slot == 1 then return -0.32 elseif slot == 2 then return -0.535 end elseif lablen == 3 then if slot == 0 then return -0.21 elseif slot == 1 then return -0.43 end elseif lablen == 4 then return -0.32 end end while i <= #buttonlist do local lastone=i == #buttonlist local curra,currb local test=whatlist[i] == "" if test then curra,currb=makecopytab(frame,1),makecopytab(frame,1) else curra=makecopytab(frame,1) end local formatted local formtype=numinter(buttonlist[i],nil,true) if formtype == "1" then formatted=string.format("%d",buttonlist[i]) else formatted=buttonlist[i] end local poslab=(test and "+" or (whatlist[i]))..formatted local neglab="-"..formatted local lablen=math.ceil(string.len(poslab)/4.5) if lablen > 4 then lablen=4; end curra.click_function=curra.click_function..(i-1+halfi)*2 if test then currb.click_function=currb.click_function..(i-1+halfi)*2+1 attachIndex("button",(i-1+halfi)*2) attachIndex("button",(i-1+halfi)*2+1) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=neglab if slot+lablen > 4 then line=line+1; slot=0; end currb.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) currb.width=lablen * currb.width currb.label=poslab self.createButton(curra) self.createButton(currb) else attachIndex("button",(i-1+halfi)*2) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=poslab self.createButton(curra) halfi=halfi-0.5 end i=i+1 end end function dummy() end function attachIndex(click_function, index) -- function to create multiple versions of function local fn_name = click_function .. index _G[fn_name] = function(obj, player_color, alt_click) _G[click_function](obj, player_color, alt_click, index) end return fn_name end function getTotalValue() if extendCounterObjs == nil then if extendCounterCoin == nil then local var=tonumber(self.getValue()) or 0 return var,var < 0,1 else local minus local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end return (minus and -math.abs(tonumber(self.getValue()) or 0) or math.abs(tonumber(self.getValue()) or 0)),minus,1 end else local meCounterIndex local i=1 while i <= #extendCounterObjs do if extendCounterObjs[i] == self then meCounterIndex=i end if extendCounterObjs[i] == nil then log("linked counter operation, counter "..i.." removed.") table.remove(extendCounterObjs,i) i=i-1 end i=i+1 end if #extendCounterObjs <= 1 then printToAll("[ff0000]ERROR:[-]Only one counter left, and started linkked counter operation.") extendCounterObjs=nil updateContextMenu() return getTotalValue() end if meCounterIndex == nil then printToAll("[ff0000]ERROR:[-]did not find index of counter."); return nil,nil,nil end local var=0 i=#extendCounterObjs local minus if extendCounterCoin == nil then minus=false else local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end end while i >= 1 do var=math.abs(tonumber(extendCounterObjs[i].getValue()) or 0) + var * 10000 i=i-1 end return (minus and -var or var),minus,meCounterIndex end end function setTotalValue(tab) local var,minus if type(tab).."" == "table" then if #tab >= 1 then var=tab[1] end if #tab >= 2 then minus=tab[2] end else log("setTotalValue:not a table") end if extendCounterObjs == nil then if minus == nil then minus=var < 0 end if minus and extendCounterCoin == nil then var=math.abs(var) % (minus and 1000 or 10000) elseif extendCounterCoin != nil then var=math.abs(var) % 10000 local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end if extendCounterCoin == nil then self.setValue(minus and -var or var) else self.setValue(var) end else if minus == nil then minus=var < 0 end var=var % math.pow(10000,#extendCounterObjs) if minus and extendCounterCoin == nil then var=math.pow(10000,#extendCounterObjs) - var elseif extendCounterCoin != nil then local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end i=#extendCounterObjs while i >= 1 do extendCounterObjs[i].setValue(math.floor(var/math.pow(10000,i-1)) % 10000) i=i-1 end end end function button(obj, col, alt_click, index) local list=self.getButtons() local var,minus,meCounterIndex=getTotalValue() local currlabel=list[index+1].label local oplett=string.sub(currlabel,1,1) local addable=numinter(string.sub(currlabel,2),0) var,minus=rawCalcOperation(oplett,var,addable * math.pow(10000,meCounterIndex-1),minus,false) setTotalValue({var,minus}) end function wrapCalcOperation(tab) local a,b,c,d,e if type(tab).."" == "table" then if #tab >= 1 then a=tab[1] end if #tab >= 2 then b=tab[2] end if #tab >= 3 then c=tab[3] end if #tab >= 4 then d=tab[4] end if #tab >= 5 then e=tab[5] end for name, item in pairs(tab) do if name == "oplett" then a=item elseif name == "var" then b=item elseif name == "addable" then c=item elseif name == "minus" then d=item elseif name == "addmeg" then e=item end end local var,minus=rawCalcOperation(a,b,c,d,e) return var,minus else log("wrapCalcOperation:not a table") return nil,nil end end function rawCalcOperation(oplett,var,addable,minus,addneg) if minus == nil then if var < 0 then minus=true else minus=false end end if addneg == nil then if addable < 0 then addneg=true else addneg=false end end if isOperator(oplett) then -- if oplett == "+" or oplett == "-" then -- if oplett == "-" and minus then -- oplett="+" -- elseif oplett == "+" and minus then -- oplett="-" -- end -- end else log("rawCalcOperation:Wrong operator") end if minus == addneg then local pah if oplett == "-" and minus then oplett = "+" end pah,var=isOperator(oplett,var,addable) else local pah if oplett == "-" then oplett = "+" elseif oplett == "+" then oplett = "-" end if minus then -- addable positive, var negative pah,var=isOperator(oplett,var,addable) else -- addable negative, var positive pah,var=isOperator(oplett,var,addable) end end if coinzero == 0 then if var < 0 then minus=not minus end elseif coinzero == -1 then if var < 0 then minus=not minus elseif 0 == var then minus=true end elseif coinzero == 1 then if var < 0 then minus=not minus elseif 0 == var then minus=false end elseif coinzero == 2 then if var >= 0 then minus=not minus end elseif coinzero == -2 then if var < 0 then minus=not minus end end return math.abs(var),minus end function isOperator(str,a,b) if type(str).."" == "string" then if string.len(str) == 1 then if type(a).."" == "number" and type(b).."" == "number" then a,b=math.abs(a),math.abs(b) if str == "+" then return true,a+b elseif str == "-" then return true,a-b elseif str == "*" then local pa,pb=a%100000000,b%100000000 local ba,bb=(a-pa)/100000000,(b-pb)/100000000 return true,pa*pb + ((ba*pb)%100000000)*100000000 + ((bb*pa)%100000000)*100000000 elseif str == "/" then return true,math.floor(a/b) elseif str == "&" then local ta,tb=a,b local i=0 local num=0 while ta != 0 and tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == cb and ca == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "|" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == 1 or cb == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "^" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if (ca == 1 and cb == 0) or (ca == 0 and cb == 1) then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "%" then return true,a%b elseif str == "<" then if b == 0 then return true,a end return true,a * math.pow(2,b) elseif str == ">" then if b == 0 then return true,a end return true,math.floor(a / math.pow(2,b)) elseif str == "p" then return true,math.floor(math.pow(a,b)) elseif str == "r" then return true,math.floor(math.pow(a,1.0/b)) end else if str == "+" then return true end if str == "-" then return true end if str == "*" then return true end if str == "/" then return true end if str == "&" then return true end if str == "|" then return true end if str == "^" then return true end if str == "%" then return true end if str == "<" then return true end if str == ">" then return true end if str == "p" then return true end if str == "r" then return true end end else log("isOperator:only one mark accepted ("..str..")") end else log("isOperator:only strings (of one character) accepted") end return false end function numinter(num,default,indentify) if type(num).."" == "number" then return num end if type(num).."" == "string" then local check="0123456789abcdefghijklmnopqrstuvwxyz" local out=nil if string.sub(num,1,1) == "0" then --hex or octaconal if string.sub(num,2,2) == "x" then --hex (base 16) if indentify then return "x" end local i=3 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:hex:not regonized character (".. c ..")"); elseif f >= 1 and f <= 16 then out=(out or 0) * 16 + f - 1 else log("numinter:hex:character out of bounds (".. (f-1) .. ")") end i=i+1 end else --octaconal (base 8) if indentify then return "0" end local i=2 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:octa:not regonized character (".. c ..")"); elseif f >= 1 and f <= 8 then out=(out or 0) * 8 + f - 1 else log("numinter:octa:character out of bounds (".. (f-1) .. "),(".. c ..")") end i=i+1 end end else if indentify then return "1" end out=tonumber(num) end if out == nil then return default else return out end end return default end function readDesc() local buttonlist={} local whatlist={} local desc=self.getDescription() or "" local txtstep=string.find(desc,",",1,true) if txtstep != nil then local prevstep repeat local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),txtstep-1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end prevstep=txtstep txtstep=string.find(desc,",",txtstep+1,true) until txtstep == nil or txtstep == string.len(desc) if textstep == nil then local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),string.len(desc)) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end elseif string.len(desc) > 0 then local poper=string.sub(desc,1,1) local test=isOperator(poper) local num=string.sub(desc,test and 2 or 1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end return buttonlist,whatlist end function makecopytab(tab,depth) local mydepth=depth or 0 if mydepth < 0 then log("this should not have been called. makecopytab") log(tab) return nil end local newtab={} if type(tab).."" == "table" then for x, val in pairs(tab) do if type(x).."" == "number" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then table.insert(newtab,x,Vector(tab[x])) else if mydepth > 0 then table.insert(newtab,x,makecopytab(tab[x],mydepth-1)) else table.insert(newtab,x,{}) end end else table.insert(newtab,x,tab[x]) end elseif type(x).."" == "string" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then newtab[x]=Vector(tab[x]) else if mydepth > 0 then newtab[x]=makecopytab(tab[x],mydepth-1) else newtab[x]={} end end else newtab[x]=tab[x] end end end else return tab end return newtab end function vectorRotate(vec,rot) return vec:rotateOver("z",rot.z):rotateOver("x",rot.x):rotateOver("y",rot.y) end function vectorIRotate(vec,rot) return vec:rotateOver("y",rot.y):rotateOver("x",rot.x):rotateOver("z",rot.z) end function vectorToLocal(target,objvec,objscale,objrot) local copy=Vector(target) copy=copy-(objvec or Vector(0,0,0)) copy=vectorIRotate(copy,(objrot or Vector(0,0,0)):inverse()) local tmp=objscale or Vector(1,1,1) copy=Vector(copy.x / tmp.x,copy.y / tmp.y, copy.z / tmp.z) return copy end function wrapVectorToLocal(tab) return vectorToLocal(tab[1],tab[2],tab[3],tab[4]) end function findInRadiusBy(pos, radius, func, debug) --by MrStump https://steamcommunity.com/sharedfiles/filedetails/?id=752690530&searchtext=lua --if DEBUG then log(" findInRadiusBy(): just called") end local radius = (radius or 1) local objList = Physics.cast({ origin=pos, direction={0,1,0}, type=2, size={radius,radius,radius}, max_distance=0, debug=(debug or false) }) local refinedList = {} for _, obj in ipairs(objList) do if func == nil then if obj.hit_object.type != "Surface" then -- Finaryman Mod table.insert(refinedList, obj.hit_object) end else if func(obj.hit_object) and obj.hit_object.type != "Surface" then --Finaryman Mod table.insert(refinedList, obj.hit_object) end end end return refinedList endLuaScriptState[]XmlUI198]GUID939525Name HandTriggerTransform‰posXà~PÀposYí@posZ€î 8@rotX€rotY ̉V@rotZscaleXÀ3Ì/@scaleY@scaleZ É$ @NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1r€t“È?g€—næ?bÀ�Å?aLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsFogColorGreenLuaScriptLuaScriptStateXmlUI199^GUIDe564acName HandTriggerTransform‰posX@•PÀposYí@posZ@Ì¡?rotX€rotY ̉V@rotZscaleX`Eã/@scaleY@scaleZÀ½î@NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1r@bä?g ÿÿ¿?b¬î?aLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsFogColorPurpleLuaScriptLuaScriptStateXmlUI200]GUID5034b1Name HandTriggerTransform‰posX@ËPÀposYí@posZàFü7ÀrotX€rotY ̉V@rotZscaleX H0@scaleY@scaleZ€ù @NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse1rð?gð?bð?aLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsFogColorWhiteLuaScriptLuaScriptStateXmlUI201ÝGUID520c57NameDeckTransform‰posX@�G@posYŠó?posZÀÙï@rotX@«J?rotYÙf@rotZ@?b¿scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsSidewaysCardDeckIDs!0ô1ô2ô3ôCustomDeck>56FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812337/4AE27DA3F5E94ABAD1449F23214A6B0849B20536/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812337/4AE27DA3F5E94ABAD1449F23214A6B0849B20536/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUIContainedObjectsù0ºGUID4cf444Name CardCustomTransform‰posX@�G@posY`/ó?posZàÙï@rotX`|L?rotY v€f@rotZ æ¨c¿scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDôSidewaysCardCustomDeck>56FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812337/4AE27DA3F5E94ABAD1449F23214A6B0849B20536/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812337/4AE27DA3F5E94ABAD1449F23214A6B0849B20536/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI1ºGUID37b6dbName CardCustomTransform‰posX@4æI@posY€Nà@posZ@ól÷¿rotX€î«0?rotYÙf@rotZ SK¿scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDôSidewaysCardCustomDeck>56FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812337/4AE27DA3F5E94ABAD1449F23214A6B0849B20536/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812337/4AE27DA3F5E94ABAD1449F23214A6B0849B20536/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI2ºGUID29d607Name CardCustomTransform‰posXnžJ@posYmX@posZoâ¿rotXJðb¿rotY€}f@rotZ€‘oF?scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDôSidewaysCardCustomDeck>56FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812337/4AE27DA3F5E94ABAD1449F23214A6B0849B20536/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812337/4AE27DA3F5E94ABAD1449F23214A6B0849B20536/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI3ºGUID011e92Name CardCustomTransform‰posX�J@posY È}@posZÀ]xÀrotX c¿rotY 8€f@rotZ€îM?scaleX€ -ü?scaleYð?scaleZ€ -ü?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rÀÒÒæ?gÀÒÒæ?bÀÒÒæ?Tags0ShareLayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCardIDôSidewaysCardCustomDeck>56FaceURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812337/4AE27DA3F5E94ABAD1449F23214A6B0849B20536/BackURLjhttps://steamusercontent-a.akamaihd.net/ugc/2424718567238812337/4AE27DA3F5E94ABAD1449F23214A6B0849B20536/NumWidthNumHeightBackIsHiddenUniqueBackTypeLuaScriptLuaScriptStateXmlUI202’GUIDe4cf97Name3DTextTransform‰posX L{A@posY@fï?posZÀ^2ÀrotX€V@rotY ±}v@rotZscaleXð?scaleYð?scaleZð?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsTextSTextNYCcolorstate&rÀt“È?g€—næ?b �Å?fontSize�LuaScriptLuaScriptStateXmlUI203’GUID4ca0e9Name3DTextTransform‰posX@fŠA@posY ìeï?posZ bœ ÀrotX€V@rotY ±}v@rotZscaleXð?scaleYð?scaleZð?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsTextSTextC&Ocolorstate&r€Âõì?g€j¼ì?b Æ?fontSize�LuaScriptLuaScriptStateXmlUI204’GUID9a8a00Name3DTextTransform‰posX 9ˆA@posYÌfï?posZ ÇÆ'@rotX€V@rotY ±}v@rotZscaleXð?scaleYð?scaleZð?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsTextSTextB&Ocolorstate&r€?5¾?g€Âõà?bð?fontSize�LuaScriptLuaScriptStateXmlUI205’GUIDb7aebaName3DTextTransform‰posX€%‚A@posY@pgï?posZ =á:@rotX€V@rotY ±}v@rotZscaleXð?scaleYð?scaleZð?NicknameDescriptionGMNotesAltLookAngle&xyzColorDiffuse&rð?gð?bð?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsTextSTextPRRcolorstate&r Zdë?g ™™¹?b@b¸?fontSize�LuaScriptLuaScriptStateXmlUI206Ó¥GUIDa21f0cNameCounterTransform‰posXÀ%@posYCï@posZ`ƒ©2ÀrotX`(1r>rotYÀ� T¿rotZÀ%°¾scaleX€ÿÿû?scaleY€ÿÿû?scaleZ€ÿÿû?NicknameMoneyDescription 2,5,10,25GMNotesAltLookAngle&xyzColorDiffuse&r€ÿÿÏ?g€ÿÿÏ?b€ÿÿÏ?LayoutGroupSortIndexValueLockedGridSnapIgnoreFoWMeasureMovementDragSelectableAutoraiseStickyTooltipGridProjectionHideWhenFaceDownHandsCountervalueLuaScriptq£function onLoad(str) --In code settings-- invertcoin=false --old negative value is now positive and old positive value is now negative coinzero=-2 --0 > toggle when beond zero, -1 > zero is negative, 1 > zero is positive, 2 > toggle when reached zero, -2 > zero is special autoconnect=true --allow autoconnecting by putting counters next to each other howfaraconn=0.6 --how far autoconnect works (object scale affects this) showcalcround=true --show autocalculation list on hover --End of settings--- savechanged=false local start=false SETTINGS_POS=string.find(self.script_code,"--End of settings---") self.setVar("SETTINGS_POS",SETTINGS_POS) if str != "" and str != nil then local data=JSON.decode(str) for name, info in pairs(data) do if name == "extendCounterObjs" then if type(info).."" == "table" then if #info > 1 then extendCounterObjs={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(extendCounterObjs,obj) end end if #extendCounterObjs < 2 then extendCounterObjs=nil end end end end if name == "extendCounterCoin" then local obj=getObjectFromGUID(info) if obj then extendCounterCoin=obj end end if name == "autoCalculateList" then if type(info).."" == "table" then if #info > 2 then autoCalculateList={} for _, guid in ipairs(info) do local obj=getObjectFromGUID(guid) if obj then table.insert(autoCalculateList,obj) end end if #autoCalculateList < 3 then autoCalculateList=nil else start=true end end end end end end self.setVar("whatIAm","Counter") self.setVar("Supports_getTotalValue",true) self.setVar("whatIAmSpecfically","[finmod]Advanced Counter Mark II") watchDesc() updateContextMenu() if start then autoCalculateActive=false; autocalcOperation(); end end function onSave() local objs={} local autol={} local rettab={} local coin if savechanged then if extendCounterCoin then coin=extendCounterCoin.getGUID() end if type(extendCounterObjs).."" == "table" then for _, obj in ipairs(extendCounterObjs) do if obj then table.insert(objs,obj.getGUID()) end end end if type(autoCalculateList).."" == "table" then for _, obj in ipairs(autoCalculateList) do if obj then table.insert(autol,obj.getGUID()) end end end if #objs > 1 then rettab["extendCounterObjs"]=objs end if coin then rettab["extendCounterCoin"]=coin end if #autol > 2 then rettab["autoCalculateList"]=autol end savechanged=false return JSON.encode(rettab) else return self.script_state end end function getAnyVar(tab) return _G[tab[1]] end function setAnyVar(tab) _G[tab[1]]=tab[2] end function onHover(col) if autoCalculateList != nil and showcalcround then local showme={ color=Color(1,1,1), thickness=0.1, rotation=Vector(0,0,0), points={} } local pos=self.getPosition()+Vector(0,0.5,0) local ipos=self.getPosition()-Vector(0,1.5,0) local prevvec=vectorToLocal(pos,self.getPosition(),self.getScale(),self.getRotation()) local list={} i=#autoCalculateList while i > 0 do showme.color=Color(1,1,1):lerp(Color(0,0,1),(#autoCalculateList-i)/(#autoCalculateList-1)) table.insert(list,makecopytab(showme,1)) list[#autoCalculateList-i+1].points[1]=prevvec local obj=autoCalculateList[i] list[#autoCalculateList-i+1].points[2]=vectorToLocal(obj.getPosition(),ipos,self.getScale()*Vector(3,3,3),self.getRotation()) prevvec=list[#autoCalculateList-i+1].points[2] i=i-1 end self.setVectorLines(list) Wait.time(function() self.setVectorLines() end, 3.0) end end function onPickUp(color) if type(extendCounterObjs).."" == "table" then local amount=#extendCounterObjs local selob=Player[color].getSelectedObjects() if selob then if #selob == amount then for i=1, amount do local test = false for x=1, amount do if selob[i] == extendCounterObjs[x] then test=true end end if test then return end end end end for i, obj in ipairs(extendCounterObjs) do if obj then if string.sub(obj.script_code,obj.getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or obj.getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then obj.call("extflash",{nil}) obj.call("updateContextMenu") else local guid=obj.getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end end end end printToAll("broke connection of ".. amount .." counters.") end end function onDrop(color) startChecking() end function startChecking() if autoconnect then preCheck(os.time()+3) end end function preCheck(secs) if os.time() < secs then if not self.resting and checkWait == nil then checkWait=Wait.time(function() preCheck(secs) end,0.1) else checkWait=nil checkConnections() end else checkWait=nil end end function checkConnections() local finallist={self} local bd=self.getBounds() local scale=self.getScale() local x=bd.size.x / 2.0 local rot=self.getRotation() local left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) local right=Vector()-left local cpos=self.getPosition() local tmppos=cpos local test=true while test do local list=findInRadiusBy(tmppos+left,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 left=Vector(-(x+(howfaraconn+0.5)*scale.x),-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,list[1]) else test=false end end tmppos=cpos test=true while test do local list=findInRadiusBy(tmppos+right,1.0,function(obj) return obj.type == "Counter" end) if #list > 0 then tmppos=list[1].getPosition() bd=list[1].getBounds() scale=list[1].getScale() x=bd.size.x / 2.0 right=Vector(x+(howfaraconn+0.5)*scale.x,-bd.offset.y,0):rotateOver("y",rot.y) table.insert(finallist,1,list[1]) else test=false end end if #finallist <= 1 then return end local coin=extendCounterCoin for i=1,#finallist do if string.sub(finallist[i].script_code,finallist[i].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or finallist[i].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then finallist[i].call("extflash",{finallist}) if coin then finallist[i].call("scriptcoin",{coin,invertcoin,coinzero}) end else local guid=finallist[i].getGUID() for i=1, 7 do Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end end printToAll("Connected ".. #finallist .." counters.") end function watchDesc() if savedDesc != self.getDescription() then local a,b=readDesc() createButtons(a,b) savedDesc=self.getDescription() end if savedTint != self.getColorTint() then local a,b=readDesc() createButtons(a,b) savedTint=self.getColorTint() end Wait.time(watchDesc,0.5) end function updateContextMenu() self.clearContextMenu() self.addContextMenuItem("extend counter",extendc) if extendCounterObjs != nil then self.addContextMenuItem("clear",function() local a,minus,c=getTotalValue(); if coinzero == -1 then minus=true elseif coinzero == 1 then minus=false elseif coinzero == 2 then minus=not minus end setTotalValue({0,minus}) end) end self.addContextMenuItem("make autocalc",autocalc) savechanged=true end function extendc(col) if col == nil then extendCounterObjs=nil return end extendCounterObjs=Player[col].getSelectedObjects() extendCounterCoin=nil if extendCounterObjs != nil then if #extendCounterObjs <= 1 then extendCounterObjs=nil elseif #extendCounterObjs >= 2 then -- if self != extendCounterObjs[1] then -- printToAll("[ff0000]ERROR:[-]select smallest counter first, and from smallest counter right click menu.") -- return -- end if extendCounterObjs[i].type.."" != "Counter" then local i=1 while i <= #extendCounterObjs do if string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) and extendCounterObjs[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then local typetest=extendCounterObjs[i].type.."" == "Counter" or (extendCounterObjs[i].getVar("whatIAm") == "Counter") if i == 2 then if i == #extendCounterObjs then extendCounterCoin=extendCounterObjs[#extendCounterObjs] extendCounterObjs=nil return end elseif i == #extendCounterObjs and not typetest then log("LinkkingCounters:we assume this is coin (negitve display)") extendCounterCoin=extendCounterObjs[#extendCounterObjs] table.remove(extendCounterObjs) elseif typetest then printToAll("[ff0000]ERROR:[-]Unknown counter (possibly unexpected behaviour).") else table.remove(extendCounterObjs,i) i=i-1 end elseif string.sub(self.script_code,SETTINGS_POS) != string.sub(extendCounterObjs[i].script_code,extendCounterObjs[i].getVar("SETTINGS_POS") or SETTINGS_POS) then printToAll("[ff0000]ERROR:[-]Counters not the same version (Advanced Counter Mark II) (possibly unexpected behaviour).") end i=i+1 end if #extendCounterObjs >= 2 then extendCounterObjs[1].call("scriptext",{extendCounterObjs,1}) end for i=1, #extendCounterObjs do if extendCounterObjs[i] != self then extendCounterObjs[i].call("scriptcoin",{extendCounterCoin,invertcoin,coinzero}) end end end end updateContextMenu() end function autocalc(col) savechanged=true autoCalculateList=nil if col == nil then return end autoCalculateList=Player[col].getSelectedObjects() Player[col].clearSelectedObjects() if autoCalculateList == nil then return end local i=1 while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i != #autoCalculateList then local test=isOperator(autoCalculateList[i].getName()) if not test then test=isOperator(autoCalculateList[i].getDescription()) end if not test then printToAll("[ff0000]ERROR:[-]autocalc: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) else local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,0),0.45) end, i*0.3+0.7) end else if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" then log("non Advanced Counter Mark II detected (or too old version). "..i) else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then log("other version of Advanced Counter Mark II detected. "..i) else log("[00ff00]OK:[-]same version of Advanced Counter Mark II detected. "..i) end end local guid=autoCalculateList[i].getGUID() Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.45) end, i*0.3+0.7) end i=i+1 end log(autoCalculateList) table.remove(autoCalculateList) -- remove self if #autoCalculateList > 1 and ((#autoCalculateList % 2) == 1) then autoCalculateActive=false autocalcOperation() else printToAll("[ff0000]ERROR:[-] ".. #autoCalculateList .." long list failed (dropped). Select odd number of objects, starting from counter, then finally select counter to display the value (paired number of selected objects).") autoCalculateList=nil end end function autocalcOperation() if autoCalculateList != nil then if not autoCalculateActive then autoCalculateActive=true local i=1 local lastop local mycalc,myminus=0,false while i <= #autoCalculateList do local isop=i%2 == 0 if isop then if i == #autoCalculateList then printToAll("[ff0000]ERROR:[-]autocalcOperation: last one cannot be operator.") end local test=isOperator(autoCalculateList[i].getName()) if test then lastop=autoCalculateList[i].getName() else test=isOperator(autoCalculateList[i].getDescription()) if test then lastop=autoCalculateList[i].getDescription() else printToAll("[ff0000]ERROR:[-]autocalcOperation: ".. i .." index selected not an operator. (dropped)") table.remove(autoCalculateList,i) i=i-1 end end else local var,minus,index if autoCalculateList[i].getVar("whatIAmSpecfically") != "[finmod]Advanced Counter Mark II" and not autoCalculateList[i].getVar("Supports_getTotalValue") then var=autoCalculateList[i].getValue() minus=var < 0 else if string.sub(autoCalculateList[i].script_code,autoCalculateList[i].getVar("SETTINGS_POS") or SETTINGS_POS) != string.sub(self.script_code,SETTINGS_POS) then var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) else var,minus,index=autoCalculateList[i].call("getTotalValue") var=math.floor(var / math.pow(10000,index-1)) end end if i == 1 then mycalc=math.abs(var) myminus=minus else mycalc,myminus=rawCalcOperation(lastop,mycalc,var,myminus,minus) end end i=i+1 end setTotalValue({mycalc,myminus}) autoCalculateActive=false autoCalculateWait=Wait.time(autocalcOperation,1.0) end end end function debugme() log(extendCounterObjs) log(extendCounterCoin) if autoCalculateList != nil then for i, obj in ipairs(autoCalculateList) do local guid=obj.getGUID() local times=#autoCalculateList Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 0) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 1) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 2) Wait.time(function() getObjectFromGUID(guid).highlightOn(Color(1,1,1),0.3) end,0.1 + 0.3*i + times * 0.3 * 3) end else log("nil") end local a,b=readDesc() log(a) log(b) end function extflash(tab) if tab[1] == nil then for i=1, 7 do Wait.time(function() self.highlightOn(Color(1,0,0),0.2) end,(-0.2)+0.4*i) end else for i=1, 7 do Wait.time(function() self.highlightOn(Color(0,1,0),0.2) end,(-0.2)+0.4*i) end end extset(tab) end function extset(tab) extendCounterObjs=tab[1] updateContextMenu() end function scriptext(tab) if #tab[1] >= tab[2] then extendCounterObjs=tab[1] if #tab[1] > tab[2] then if string.sub(tab[1][tab[2]+1].script_code,tab[1][tab[2]+1].getVar("SETTINGS_POS") or SETTINGS_POS) == string.sub(self.script_code,SETTINGS_POS) or tab[1][tab[2]+1].getVar("whatIAmSpecfically") == "[finmod]Advanced Counter Mark II" then tab[1][tab[2]+1].call("scriptext",{tab[1],tab[2]+1}) else -- end end updateContextMenu() end end function scriptcoin(coin) extendCounterCoin=coin[1] if #coin > 1 then if coin[2] != nil then invertcoin=coin[2] end if #coin > 2 then if coin[3] != nil then coinzero=coin[3] end end end end function createButtons(buttonlist,whatlist) self.clearButtons() local bgcol=self.getColorTint() local test=(bgcol.r * 0.3 + bgcol.r * 0.3 * (1-bgcol.g) + bgcol.g + bgcol.b * 0.4 > 0.925) local txtcol=test and Color(1,1,1) or Color(0,0,0) local buttcol=test and Color(0.2,0.2,0.2) or Color(0.8,0.8,0.8) local butthov=Color(0.5,0.5,0.5) --[[ self.createButton({ click_function=nil, function_owner=self, label=" ", position=Vector(0,0.2,-0.4-(math.ceil(#buttonlist/2)*0.08-0.08)), scale=Vector(0.1,1,0.1), width=4500, height=800*math.ceil(#buttonlist/2)+200, color={bgcol.r,bgcol.g,bgcol.b}, hover_color={bgcol.r,bgcol.g,bgcol.b}, press_color={bgcol.r,bgcol.g,bgcol.b} })]] local buttonorginpos=Vector(0.32,0.201,-0.41) local frame={ click_function="button", function_owner=self, label=" ", font_size=400, position=buttonorginpos, rotation=Vector(0,180,0), scale=Vector(0.1,1,0.1), width=1000, height=600, color={buttcol.r,buttcol.g,buttcol.b}, hover_color={butthov.r,butthov.g,butthov.b}, press_color={butthov.r,butthov.g,butthov.b}, font_color={txtcol.r,txtcol.g,txtcol.b} } local i=1 local slot=0 local line=0 local halfi=0 local function slothand(slot,lablen) if lablen == 1 then if slot == 0 then return 0 elseif slot == 1 then return -0.21 elseif slot == 2 then return -0.43 elseif slot == 3 then return -0.64 end elseif lablen == 2 then if slot == 0 then return -0.105 elseif slot == 1 then return -0.32 elseif slot == 2 then return -0.535 end elseif lablen == 3 then if slot == 0 then return -0.21 elseif slot == 1 then return -0.43 end elseif lablen == 4 then return -0.32 end end while i <= #buttonlist do local lastone=i == #buttonlist local curra,currb local test=whatlist[i] == "" if test then curra,currb=makecopytab(frame,1),makecopytab(frame,1) else curra=makecopytab(frame,1) end local formatted local formtype=numinter(buttonlist[i],nil,true) if formtype == "1" then formatted=string.format("%d",buttonlist[i]) else formatted=buttonlist[i] end local poslab=(test and "+" or (whatlist[i]))..formatted local neglab="-"..formatted local lablen=math.ceil(string.len(poslab)/4.5) if lablen > 4 then lablen=4; end curra.click_function=curra.click_function..(i-1+halfi)*2 if test then currb.click_function=currb.click_function..(i-1+halfi)*2+1 attachIndex("button",(i-1+halfi)*2) attachIndex("button",(i-1+halfi)*2+1) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=neglab if slot+lablen > 4 then line=line+1; slot=0; end currb.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) currb.width=lablen * currb.width currb.label=poslab self.createButton(curra) self.createButton(currb) else attachIndex("button",(i-1+halfi)*2) if slot+lablen > 4 then line=line+1; slot=0; end curra.position=buttonorginpos+Vector(slothand(slot,lablen),0,-(line*0.16)) slot=(slot+lablen) curra.width=lablen * curra.width curra.label=poslab self.createButton(curra) halfi=halfi-0.5 end i=i+1 end end function dummy() end function attachIndex(click_function, index) -- function to create multiple versions of function local fn_name = click_function .. index _G[fn_name] = function(obj, player_color, alt_click) _G[click_function](obj, player_color, alt_click, index) end return fn_name end function getTotalValue() if extendCounterObjs == nil then if extendCounterCoin == nil then local var=tonumber(self.getValue()) or 0 return var,var < 0,1 else local minus local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end return (minus and -math.abs(tonumber(self.getValue()) or 0) or math.abs(tonumber(self.getValue()) or 0)),minus,1 end else local meCounterIndex local i=1 while i <= #extendCounterObjs do if extendCounterObjs[i] == self then meCounterIndex=i end if extendCounterObjs[i] == nil then log("linked counter operation, counter "..i.." removed.") table.remove(extendCounterObjs,i) i=i-1 end i=i+1 end if #extendCounterObjs <= 1 then printToAll("[ff0000]ERROR:[-]Only one counter left, and started linkked counter operation.") extendCounterObjs=nil updateContextMenu() return getTotalValue() end if meCounterIndex == nil then printToAll("[ff0000]ERROR:[-]did not find index of counter."); return nil,nil,nil end local var=0 i=#extendCounterObjs local minus if extendCounterCoin == nil then minus=false else local vec=vectorRotate(Vector(0,1,0),extendCounterCoin.getRotation()) if vec.y <= -0.15 then minus=false != invertcoin elseif vec.y >= 0.15 then minus=true != invertcoin else minus=false != invertcoin end end while i >= 1 do var=math.abs(tonumber(extendCounterObjs[i].getValue()) or 0) + var * 10000 i=i-1 end return (minus and -var or var),minus,meCounterIndex end end function setTotalValue(tab) local var,minus if type(tab).."" == "table" then if #tab >= 1 then var=tab[1] end if #tab >= 2 then minus=tab[2] end else log("setTotalValue:not a table") end if extendCounterObjs == nil then if minus == nil then minus=var < 0 end if minus and extendCounterCoin == nil then var=math.abs(var) % (minus and 1000 or 10000) elseif extendCounterCoin != nil then var=math.abs(var) % 10000 local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end if extendCounterCoin == nil then self.setValue(minus and -var or var) else self.setValue(var) end else if minus == nil then minus=var < 0 end var=var % math.pow(10000,#extendCounterObjs) if minus and extendCounterCoin == nil then var=math.pow(10000,#extendCounterObjs) - var elseif extendCounterCoin != nil then local tmpminus if invertcoin then tmpminus=not minus else tmpminus=minus end if coinzero == -2 and var == 0 then extendCounterCoin.setRotation(Vector(0,0,90)) elseif tmpminus then extendCounterCoin.setRotation(Vector(0,0,0)) else extendCounterCoin.setRotation(Vector(0,0,180)) end end i=#extendCounterObjs while i >= 1 do extendCounterObjs[i].setValue(math.floor(var/math.pow(10000,i-1)) % 10000) i=i-1 end end end function button(obj, col, alt_click, index) local list=self.getButtons() local var,minus,meCounterIndex=getTotalValue() local currlabel=list[index+1].label local oplett=string.sub(currlabel,1,1) local addable=numinter(string.sub(currlabel,2),0) var,minus=rawCalcOperation(oplett,var,addable * math.pow(10000,meCounterIndex-1),minus,false) setTotalValue({var,minus}) end function wrapCalcOperation(tab) local a,b,c,d,e if type(tab).."" == "table" then if #tab >= 1 then a=tab[1] end if #tab >= 2 then b=tab[2] end if #tab >= 3 then c=tab[3] end if #tab >= 4 then d=tab[4] end if #tab >= 5 then e=tab[5] end for name, item in pairs(tab) do if name == "oplett" then a=item elseif name == "var" then b=item elseif name == "addable" then c=item elseif name == "minus" then d=item elseif name == "addmeg" then e=item end end local var,minus=rawCalcOperation(a,b,c,d,e) return var,minus else log("wrapCalcOperation:not a table") return nil,nil end end function rawCalcOperation(oplett,var,addable,minus,addneg) if minus == nil then if var < 0 then minus=true else minus=false end end if addneg == nil then if addable < 0 then addneg=true else addneg=false end end if isOperator(oplett) then -- if oplett == "+" or oplett == "-" then -- if oplett == "-" and minus then -- oplett="+" -- elseif oplett == "+" and minus then -- oplett="-" -- end -- end else log("rawCalcOperation:Wrong operator") end if minus == addneg then local pah if oplett == "-" and minus then oplett = "+" end pah,var=isOperator(oplett,var,addable) else local pah if oplett == "-" then oplett = "+" elseif oplett == "+" then oplett = "-" end if minus then -- addable positive, var negative pah,var=isOperator(oplett,var,addable) else -- addable negative, var positive pah,var=isOperator(oplett,var,addable) end end if coinzero == 0 then if var < 0 then minus=not minus end elseif coinzero == -1 then if var < 0 then minus=not minus elseif 0 == var then minus=true end elseif coinzero == 1 then if var < 0 then minus=not minus elseif 0 == var then minus=false end elseif coinzero == 2 then if var >= 0 then minus=not minus end elseif coinzero == -2 then if var < 0 then minus=not minus end end return math.abs(var),minus end function isOperator(str,a,b) if type(str).."" == "string" then if string.len(str) == 1 then if type(a).."" == "number" and type(b).."" == "number" then a,b=math.abs(a),math.abs(b) if str == "+" then return true,a+b elseif str == "-" then return true,a-b elseif str == "*" then local pa,pb=a%100000000,b%100000000 local ba,bb=(a-pa)/100000000,(b-pb)/100000000 return true,pa*pb + ((ba*pb)%100000000)*100000000 + ((bb*pa)%100000000)*100000000 elseif str == "/" then return true,math.floor(a/b) elseif str == "&" then local ta,tb=a,b local i=0 local num=0 while ta != 0 and tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == cb and ca == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "|" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if ca == 1 or cb == 1 then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "^" then local ta,tb=a,b local i=0 local num=0 while ta != 0 or tb != 0 do local ca,cb=ta%2,tb%2 ta,tb=(ta-ca)/2,(tb-cb)/2 if (ca == 1 and cb == 0) or (ca == 0 and cb == 1) then num=num+math.pow(2,i) end i=i+1 end return true,num elseif str == "%" then return true,a%b elseif str == "<" then if b == 0 then return true,a end return true,a * math.pow(2,b) elseif str == ">" then if b == 0 then return true,a end return true,math.floor(a / math.pow(2,b)) elseif str == "p" then return true,math.floor(math.pow(a,b)) elseif str == "r" then return true,math.floor(math.pow(a,1.0/b)) end else if str == "+" then return true end if str == "-" then return true end if str == "*" then return true end if str == "/" then return true end if str == "&" then return true end if str == "|" then return true end if str == "^" then return true end if str == "%" then return true end if str == "<" then return true end if str == ">" then return true end if str == "p" then return true end if str == "r" then return true end end else log("isOperator:only one mark accepted ("..str..")") end else log("isOperator:only strings (of one character) accepted") end return false end function numinter(num,default,indentify) if type(num).."" == "number" then return num end if type(num).."" == "string" then local check="0123456789abcdefghijklmnopqrstuvwxyz" local out=nil if string.sub(num,1,1) == "0" then --hex or octaconal if string.sub(num,2,2) == "x" then --hex (base 16) if indentify then return "x" end local i=3 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:hex:not regonized character (".. c ..")"); elseif f >= 1 and f <= 16 then out=(out or 0) * 16 + f - 1 else log("numinter:hex:character out of bounds (".. (f-1) .. ")") end i=i+1 end else --octaconal (base 8) if indentify then return "0" end local i=2 local slen=string.len(num) while i <= slen do local c=string.sub(num,i,i) local f=string.find(check,c) if f == nil then log("numinter:octa:not regonized character (".. c ..")"); elseif f >= 1 and f <= 8 then out=(out or 0) * 8 + f - 1 else log("numinter:octa:character out of bounds (".. (f-1) .. "),(".. c ..")") end i=i+1 end end else if indentify then return "1" end out=tonumber(num) end if out == nil then return default else return out end end return default end function readDesc() local buttonlist={} local whatlist={} local desc=self.getDescription() or "" local txtstep=string.find(desc,",",1,true) if txtstep != nil then local prevstep repeat local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),txtstep-1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end prevstep=txtstep txtstep=string.find(desc,",",txtstep+1,true) until txtstep == nil or txtstep == string.len(desc) if textstep == nil then local poper=string.sub(desc,(prevstep or 0)+1,(prevstep or 0)+1) local test=isOperator(poper) local num=string.sub(desc,(prevstep or 0)+1+(test and 1 or 0),string.len(desc)) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end elseif string.len(desc) > 0 then local poper=string.sub(desc,1,1) local test=isOperator(poper) local num=string.sub(desc,test and 2 or 1) or "" if string.len(num) != 0 then if test then table.insert(whatlist,poper) else table.insert(whatlist,"") end table.insert(buttonlist,num) end end return buttonlist,whatlist end function makecopytab(tab,depth) local mydepth=depth or 0 if mydepth < 0 then log("this should not have been called. makecopytab") log(tab) return nil end local newtab={} if type(tab).."" == "table" then for x, val in pairs(tab) do if type(x).."" == "number" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then table.insert(newtab,x,Vector(tab[x])) else if mydepth > 0 then table.insert(newtab,x,makecopytab(tab[x],mydepth-1)) else table.insert(newtab,x,{}) end end else table.insert(newtab,x,tab[x]) end elseif type(x).."" == "string" then if type(tab[x]).."" == "table" then if type(tab[x].x).."" == "number" and type(tab[x].y).."" == "number" and type(tab[x].z).."" == "number" then newtab[x]=Vector(tab[x]) else if mydepth > 0 then newtab[x]=makecopytab(tab[x],mydepth-1) else newtab[x]={} end end else newtab[x]=tab[x] end end end else return tab end return newtab end function vectorRotate(vec,rot) return vec:rotateOver("z",rot.z):rotateOver("x",rot.x):rotateOver("y",rot.y) end function vectorIRotate(vec,rot) return vec:rotateOver("y",rot.y):rotateOver("x",rot.x):rotateOver("z",rot.z) end function vectorToLocal(target,objvec,objscale,objrot) local copy=Vector(target) copy=copy-(objvec or Vector(0,0,0)) copy=vectorIRotate(copy,(objrot or Vector(0,0,0)):inverse()) local tmp=objscale or Vector(1,1,1) copy=Vector(copy.x / tmp.x,copy.y / tmp.y, copy.z / tmp.z) return copy end function wrapVectorToLocal(tab) return vectorToLocal(tab[1],tab[2],tab[3],tab[4]) end function findInRadiusBy(pos, radius, func, debug) --by MrStump https://steamcommunity.com/sharedfiles/filedetails/?id=752690530&searchtext=lua --if DEBUG then log(" findInRadiusBy(): just called") end local radius = (radius or 1) local objList = Physics.cast({ origin=pos, direction={0,1,0}, type=2, size={radius,radius,radius}, max_distance=0, debug=(debug or false) }) local refinedList = {} for _, obj in ipairs(objList) do if func == nil then if obj.hit_object.type != "Surface" then -- Finaryman Mod table.insert(refinedList, obj.hit_object) end else if func(obj.hit_object) and obj.hit_object.type != "Surface" then --Finaryman Mod table.insert(refinedList, obj.hit_object) end end end return refinedList endLuaScriptState[]XmlUI