Handoncloud

PhysicObject

Nov 15th, 2016 (edited)
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.53 KB | None | 0 0
  1. objl = {};
  2.  
  3. (function(exports)
  4.  
  5.   local function _isInstanceOf(Constructor, instance)
  6.     return getmetatable(instance) == Constructor.__imt;
  7.   end
  8.  
  9.   local function _checkClassMethod(Constructor, instance, className, methodName)
  10.       if not _isInstanceOf(Constructor, instance) then
  11.         error(Messages.MissingInstanceAtMethod
  12.                 :gsub('%%c', className)
  13.                 :gsub('%%m', methodName))
  14.       end
  15.   end
  16.  
  17.   local IS_MODULE_ROOM = tfm
  18.     .get
  19.     .room
  20.     .name:byte(1) == 0x23;
  21.  
  22.   local Messages = {
  23.     CannotAppendNonObject = "[objl] cannot append values except object/layer to a layer",
  24.     MissingInstanceAtMethod = "[objl] missing instance of '%c' at method '%m'"
  25.   };
  26.  
  27.   local ObjectTypes = {
  28.     PHYSIC = 0,
  29.     JOINT = 1,
  30.     SHAMAN = 2
  31.   };
  32.  
  33.   local PhysicTextureTypes = {
  34.     WOOD       = 0,
  35.     ICE        = 1,
  36.     TRAMPOLINE = 2,
  37.     LAVA       = 3,
  38.     CHOCOLATE  = 4,
  39.     EARTH      = 5,
  40.     GRASS      = 6,
  41.     SAND       = 7,
  42.     CLOUD      = 8,
  43.     WATER      = 9,
  44.     STONE      = 10,
  45.     SNOW       = 11,
  46.     COLOR      = 12,
  47.     CIRCLE     = 13,
  48.     INVISIBLE  = 14,
  49.     WEB        = 15
  50.   };
  51.  
  52.   local ShamanObjectsId = {
  53.     ARROW = 0,
  54.     LITTLEBOX = 1,
  55.     BOX = 2,
  56.     LITTLEBOARD = 3,
  57.     BOARD = 4,
  58.     BALL = 6,
  59.     TRAMPOLINE = 7,
  60.     ANVIL = 10,
  61.     CANNON = 17,
  62.     BOMB = 23,
  63.     BALLOON = 28,
  64.     RUNE = 32,
  65.     SNOWBALL = 34,
  66.     ICECUBE = 54
  67.   };
  68.  
  69.   local initialObjectsId = {
  70.     [ObjectTypes.PHYSIC] = 0,
  71.     [ObjectTypes.JOINT] = 0
  72.   };
  73.  
  74.   local objectProperties = {
  75.     [ObjectTypes.PHYSIC] = {
  76.  
  77.     },
  78.     [ObjectTypes.JOINT] = {
  79.  
  80.     },
  81.     [ObjectTypes.SHAMAN] = {
  82.       objType = true,
  83.       x = true,
  84.       y = true,
  85.       vx = true,
  86.       vy = true,
  87.       ghost = true,
  88.       rotation = true
  89.     },
  90.   };
  91.  
  92.   local naturalPhysics = {
  93.     defaults = {
  94.       damage = 0.2,
  95.       friction = 0.3
  96.     },
  97.  
  98.     [PhysicTextureTypes.ICE] = {
  99.       friction = 0
  100.     },
  101.  
  102.     [PhysicTextureTypes.TRAMPOLINE] = {
  103.       damage = 1.2,
  104.       friction = 0
  105.     },
  106.  
  107.     [PhysicTextureTypes.LAVA] = {
  108.       damage = 20,
  109.       friction = 0
  110.     },
  111.  
  112.     [PhysicTextureTypes.CHOCOLATE] = {
  113.       friction = 20
  114.     },
  115.  
  116.     [PhysicTextureTypes.CLOUD] = {
  117.       miceCollision = false
  118.     }
  119.   };
  120.  
  121.   local enumObjectTypes = {
  122.     JOINT = 0,
  123.     PHYSIC = 1,
  124.     SHAMAN = 2
  125.   };
  126.  
  127.   local objsId = {
  128.     [enumObjectTypes.JOINT] = {},
  129.     [enumObjectTypes.PHYSIC] = {}
  130.   };
  131.  
  132.   local bool, radian;
  133.  
  134.   bool = {
  135.     convert = function(value)
  136.       if value == true or
  137.          value == 1 or
  138.          value == 'true' then
  139.         return true;
  140.       end
  141.       return false;
  142.     end,
  143.  
  144.     enum = function(value)
  145.       return value and 1 or 0;
  146.     end
  147.   };
  148.  
  149.   radian = {
  150.     asDegrees = function(rad)
  151.       local pi = math.pi;
  152.       return (rad * pi) * (180 / pi);
  153.     end
  154.   };
  155.  
  156.   local function renderShamanObj(obj)
  157.     local __data = obj.__data;
  158.  
  159.     if obj.__id then
  160.       tfm.exec.removeObject(obj.__id);
  161.     end
  162.  
  163.     obj.__id = tfm.exec.addShamanObject(__data.objId, __data.x, __data.y);
  164.   end
  165.  
  166.   local freeId, objectsId, resolveNewId;
  167.  
  168.   freeId = function(objType, id)
  169.     local idList = objectsId[objType];
  170.     table.foreachi(idList, function(i, lid)
  171.       if lid == id then
  172.         table.remove(idList, i);
  173.         return false;
  174.       end
  175.     end);
  176.   end;
  177.  
  178.   objectsId = {
  179.     [ ObjectTypes.JOINT ] = {},
  180.     [ ObjectTypes.PHYSIC ] = {},
  181.     [ ObjectTypes.SHAMAN ] = {}
  182.   };
  183.  
  184.   resolveNewId = function(objType)
  185.     local idList = objectsId[objType];
  186.     local idLen = #idList;
  187.     local initialId = initialObjectsId[objType];
  188.     local availableId, prevId;
  189.  
  190.     table.sort(idList);
  191.     table.foreachi(idList, function(i, id)
  192.       if prevId and id > (prevId + 1) then
  193.         availableId = id - 1;
  194.         return false;
  195.       elseif id > initialId then
  196.         availableId = initialId;
  197.         return false;
  198.       end
  199.       prevId = idList[i];
  200.     end);
  201.  
  202.     if not availableId then
  203.       if idLen > 0 then
  204.         availableId = idList[idLen] + 1;
  205.       else
  206.         availableId = initialId;
  207.       end
  208.     end
  209.  
  210.     return availableId;
  211.   end;
  212.  
  213.   local Joint, Layer, Physic, Shaman;
  214.  
  215.   Joint = {
  216.     fn = {
  217.       remove = function(self)
  218.         _checkClassMethod(Joint, self, "objl.Joint", "remove");
  219.         tfm.exec.removeJoint(self.__id);
  220.         freeId(objectTpes.JOINT, self.__id);
  221.  
  222.         for i, layer in ipairs(self.__layers) do
  223.           local bi = layer:findIndexByRef(self);
  224.           if bi > 0 then
  225.             table.remove(layer.__items, bi);
  226.           end
  227.         end
  228.  
  229.         -- gc
  230.         self.__layers = nil;
  231.         setmetatable(self, nil);
  232.       end
  233.     },
  234.   };
  235.  
  236.   Joint.__mt = {
  237.     __call = function()
  238.  
  239.     end
  240.   };
  241.  
  242.   Joint.__imt = {
  243.     __index = Joint.fn
  244.   };
  245.  
  246.   setmetatable(Joint, Joint.__mt);
  247.  
  248.   Layer = {
  249.     fn = {
  250.       append = function(self, item)
  251.         _checkClassMethod(Layer, self, "objl.Layer", "append");
  252.  
  253.         if not (_isInstanceOf(Layer, self) or
  254.                 _isInstanceOf(Physic, self) or
  255.                 _isInstanceOf(Shaman, self) or
  256.                 _isInstanceOf(Joint, self)) then
  257.           error(Messages.CannotAppendNonObject);
  258.         end
  259.  
  260.         table.insert(self.__items, item);
  261.  
  262.         if _isInstanceOf(Layer, item) then
  263.           if not item.__parents then
  264.             item.__parents = {};
  265.           end
  266.           table.insert(item.__parents, self);
  267.         else
  268.           if not item.__self then
  269.             item.__self = {};
  270.           end
  271.           table.insert(item.__layers, self);
  272.         end
  273.  
  274.         return self;
  275.       end,
  276.  
  277.       findIndexByRef = function(self, ref)
  278.         _checkClassMethod(Layer, self, "objl.Layer", "findIndexByRef");
  279.  
  280.         for i, item in ipairs(self.__items) do
  281.           if item == ref then
  282.             return i;
  283.           end
  284.         end
  285.  
  286.         return 0;
  287.       end,
  288.  
  289.       get = function(self, index)
  290.         _checkClassMethod(Layer, self, "objl.Layer", "get");
  291.         return self.__items[index];
  292.       end,
  293.  
  294.       remove = function(self, arg2)
  295.         _checkClassMethod(Layer, self, "objl.Layer", "remove");
  296.  
  297.         if not _isInstanceOf(Layer, self) then
  298.           error(Messages.MissingInstanceAtMethod
  299.                   :gsub('%i', 'objl.Layer')
  300.                   :gsub('%f', 'remove'))
  301.         end
  302.  
  303.         if arg2 then
  304.           local _type = type(arg2);
  305.           if _type == 'table' then
  306.             local i = self:findIndexByRef(arg2);
  307.             if i > 0 then
  308.               self.__items[i]:remove();
  309.             end
  310.           elseif _type == 'number' then
  311.             local item = self.__items[arg2];
  312.             if item then
  313.               self.__items[arg2]:remove();
  314.             end
  315.           else
  316.             error("bad argument #2 to 'remove' (table, nil or number expected, got ".. _type ..")");
  317.           end
  318.           return self;
  319.         end
  320.  
  321.         for i, item in ipairs(self.__items) do
  322.           item:remove();
  323.         end
  324.  
  325.         for i, layer in ipairs(self.__parents) do
  326.           local bi = layer:findIndexByRef(self);
  327.           if bi > 0 then
  328.             table.remove(layer.__parents, bi);
  329.           end
  330.         end
  331.  
  332.         -- gc
  333.         self.__items = nil;
  334.         self.__parents = nil;
  335.         setmetatable(self, nil);
  336.       end
  337.     }
  338.   };
  339.  
  340.   Layer.__mt = {
  341.     __call = function()
  342.  
  343.     end
  344.   };
  345.  
  346.   Layer.__imt = {
  347.     __index = Layer.fn
  348.   };
  349.  
  350.   setmetatable(Layer, Layer.__mt);
  351.  
  352.   Physic = {
  353.     fn = {
  354.       remove = function(self)
  355.         _checkClassMethod(Physic, self, "objl.Physic", "remove");
  356.         tfm.exec.removePhysicObject(self.__id);
  357.         freeId(objectTpes.PHYSIC, self.__id);
  358.  
  359.         for i, layer in ipairs(self.__layers) do
  360.           local bi = layer:findIndexByRef(self);
  361.           if bi > 0 then
  362.             table.remove(layer.__items, bi);
  363.           end
  364.         end
  365.  
  366.         -- gc
  367.         self.__layers = nil;
  368.         setmetatable(self, nil);
  369.       end
  370.     },
  371.   };
  372.  
  373.   Physic.__mt = {
  374.     __call = function(textureType, x, y, width, height, _options)
  375.       local instance = {
  376.         __data = {
  377.           textureType = textureType
  378.         },
  379.         __id = resolveNewId(ObjectTypes.PHYSIC),
  380.         __layers = {}
  381.       };
  382.  
  383.       setmetatable(instance, Physic.__imt);
  384.       return instance;
  385.     end
  386.   };
  387.  
  388.   Physic.__imt = {
  389.     __index = Physic.fn
  390.   };
  391.  
  392.   setmetatable(Physic, Physic.__mt);
  393.  
  394.   Shaman = {
  395.     fn = {
  396.       ghost = function(self, isGhost)
  397.         _checkClassMethod(Shaman, self, "objl.Shaman", "ghost");
  398.         if not isGhost then
  399.           return self.__data.ghost;
  400.         end
  401.         self.__data.ghost = ghost;
  402.         renderShamanObj(self);
  403.         return self;
  404.       end,
  405.  
  406.       move = function(self, x, y, offset, ...)
  407.         _checkClassMethod(Shaman, self, "objl.Shaman", "move");
  408.         local __data = self.__data;
  409.  
  410.         if offset then
  411.           if x then
  412.             __data.x = __data.x + x;
  413.           end
  414.  
  415.           if y then
  416.             __data.y = __data.y + y;
  417.           end
  418.         end
  419.  
  420.         __data.x = x or __data.x;
  421.         __data.y = y or __data.y;
  422.         tfm.exec.moveObject(self.__id, x, y, ...);
  423.         return self;
  424.       end,
  425.  
  426.       remove = function(self)
  427.         _checkClassMethod(Shaman, self, "objl.Shaman", "remove");
  428.         tfm.exec.removeObject(self.__id);
  429.  
  430.         for i, layer in ipairs(self.__layers) do
  431.           local bi = layer:findIndexByRef(self);
  432.           if bi > 0 then
  433.             table.remove(layer.__items, bi);
  434.           end
  435.         end
  436.  
  437.         -- gc
  438.         self.__layers = nil;
  439.         setmetatable(self, nil);
  440.       end,
  441.  
  442.       rotation = function(self, rads)
  443.         _checkClassMethod(Shaman, self, "objl.Shaman", "rotation");
  444.         if not rads then
  445.           return self.__data.rotation;
  446.         end
  447.         self.__data.rotation = rads;
  448.         renderShamanObj(self);
  449.         return self;
  450.       end,
  451.  
  452.       update = function(self, options)
  453.         _checkClassMethod(Shaman, self, "objl.Shaman", "update");
  454.         local _otype = type(options);
  455.         if 'table' ~= type(options) then
  456.           error("bad argument #1 to 'update' (table expected, got " .. _otype .. ")");
  457.         end
  458.  
  459.         local __data = self.__data;
  460.         local objType = ObjectTypes.SHAMAN;
  461.  
  462.         table.foreach(options, function(k, v)
  463.           if objectProperties[objType][k] then
  464.             __data[k] = v;
  465.           end
  466.         end);
  467.  
  468.         renderShamanObj(self);
  469.         return self;
  470.       end,
  471.  
  472.       x = function(self, x, offset, vx, offsetv)
  473.         _checkClassMethod(Shaman, self, "objl.Shaman", "x");
  474.         if not x then
  475.           return self.__data.x;
  476.         end
  477.         self.__data.x = x;
  478.         tfm.exec.moveObject(self.__id, x, nil, offset, vx, nil, offsetx);
  479.         return self;
  480.       end,
  481.  
  482.       y = function(self, y, offset, vy, offsetv)
  483.         _checkClassMethod(Shaman, self, "objl.Shaman", "y");
  484.         if not y then
  485.           return self.__data.y;
  486.         end
  487.         self.__data.y = y;
  488.         tfm.exec.moveObject(self.__id, nil, y, offset, nil, vy, offsetv);
  489.         return self;
  490.       end
  491.     },
  492.   };
  493.  
  494.   Shaman.__mt = {
  495.     __call = function(t, objectId, x, y, ...)
  496.       local objType = ObjectTypes.SHAMAN;
  497.  
  498.       local __data = {
  499.         objId = objectId,
  500.         x = x,
  501.         y = y
  502.       };
  503.  
  504.       local instance = {
  505.         __data = __data,
  506.         __layers = {}
  507.       };
  508.  
  509.       table.foreach({ ... }, function(i, value)
  510.         if i > 4 then
  511.           return false;
  512.         end
  513.  
  514.         if 'table' == type(value) then
  515.           table.foreach(value, function(k, v)
  516.             if objectProperties[objType][k] then
  517.               __data[k] = v;
  518.             end
  519.           end);
  520.         else
  521.           local k = (i == 1 and "rotation") or
  522.                     (i == 2 and "vx") or
  523.                     (i == 3 and "vy") or
  524.                     (i == 4 and "ghost");
  525.  
  526.           __data[k] = value;
  527.         end
  528.       end);
  529.  
  530.       setmetatable(instance, Shaman.__imt);
  531.       renderShamanObj(instance);
  532.       return instance;
  533.     end,
  534.  
  535.     __index = Shaman.fn
  536.   };
  537.  
  538.   Shaman.__imt = {
  539.     __index = Shaman.fn
  540.   };
  541.  
  542.   setmetatable(Shaman, Shaman.__mt);
  543.  
  544.   exports.initialObjectsId = initialObjectsId;
  545.   exports.naturalPhysics = naturalPhysics;
  546.   exports.Joint = Joint;
  547.   exports.Layer = Layer;
  548.   exports.Physic = Physic;
  549.   exports.PhysicTextureTypes = PhysicTextureTypes;
  550.   exports.Shaman = Shaman;
  551.  
  552. end)(objl);
Add Comment
Please, Sign In to add comment