commit 1a0785862d543ee3f5d81087929c43ce795fbb2b Author: Nikita Kruglickiy Date: Fri Dec 25 22:18:23 2020 +0600 Initial commit diff --git a/koptilnya/engine_sound.txt b/koptilnya/engine_sound.txt new file mode 100644 index 0000000..0be23f1 --- /dev/null +++ b/koptilnya/engine_sound.txt @@ -0,0 +1,79 @@ +--@include libs/utils.txt +--@client + +require("libs/utils.txt") + +EngineSound = class("EngineSound") + +accessorFunc(EngineSound, "_masterVolume", "MasterVolume", 1) +accessorFunc(EngineSound, "_parent", "Parent", chip()) + +function EngineSound:initialize(soundsMap) + self._rpm = 0 + self._soundsMap = soundsMap + self._sources = {} + + for k, v in pairs(soundsMap) do + bass.loadURL(v.link, "3d noblock", function(snd, err, errtxt) + if snd then + snd:setPos(self:getParent():getPos()) + snd:setLooping(true) + snd:setVolume(0) + + v.source = snd + table.insert(self._sources, snd) + elseif errtext then + error(errtxt) + end + end) + end + + hook.add("think", "EngineSound_think", function() + for _, v in pairs(self._sources) do + v:setPos(self:getParent():getPos()) + end + end) +end + +local function fadeIn(rpm, range) + local fadeIn = 1 + + if range and range[1] != range[2] then + fadeIn = math.min(math.max((rpm + (range[2] - range[1] * 2)) / (range[2] - range[1]), 1) - 1, 1) + end + + return fadeIn +end + +local function fadeOut(rpm, range) + local fadeOut = 1 + + if range and range[1] != range[2] then + fadeOut = math.min(math.max((rpm + (range[1] - range[2] * 2)) / (range[1] - range[2]), 1) - 1, 1) + end + + return fadeOut +end + +function EngineSound:setRPM(rpm) + self._rpm = rpm + + for _, v in pairs(self._soundsMap) do + if v.source then + local pitch = rpm / v.rootPitch + local fadeIn = fadeIn(rpm, v.fadeIn) + local fadeOut = fadeOut(rpm, v.fadeOut) + + v.source:setVolume(math.max(self:getMasterVolume() * (fadeIn + fadeOut - 1), 0.01)) + v.source:setPitch(math.max(pitch, 0.01)) + end + end +end + +function EngineSound:getRPM() + return self._rpm +end + +function EngineSound:getSources() + return self._sources +end \ No newline at end of file diff --git a/koptilnya/gui/elements/button.txt b/koptilnya/gui/elements/button.txt new file mode 100644 index 0000000..9062a5a --- /dev/null +++ b/koptilnya/gui/elements/button.txt @@ -0,0 +1,51 @@ +--@include label.txt +--@include radius_mixin.txt +--@include ../utils.txt + +require("label.txt") +require("../utils.txt") + +EButton = class("EButton", ELabel) +EButton:include(require("radius_mixin.txt")) + +accessorFunc(EButton, "_textColor", "TextColor", Color(230, 230, 230)) +accessorFunc(EButton, "_hoveredColor", "HoveredColor", Color(66, 66, 66)) +accessorFunc(EButton, "_hoveredTextColor", "HoveredTextColor", Color(230, 230, 230)) +accessorFunc(EButton, "_disabledColor", "DisabledColor", Color(32, 32, 32)) +accessorFunc(EButton, "_disabledTextColor", "DisabledTextColor", Color(80, 80, 80)) + +function EButton:initialize() + ELabel.initialize(self) + + self:setText("Button") + self:setColor(Color(46, 46, 46)) + self:setSize(100, 32) + self:setRoundedCorners(true) + self:setRadius(5) +end + +function EButton:paint() + local x, y = self:getAbsolutePos() + local w, h = self:getSize() + local textW, textH = self:getTextSize() + local rTL, rTR, rBR, rBL = self:getRoundedCorners() + local bgColor, textColor + if self:isEnabled() then + bgColor = self:isHovered() and self:getHoveredColor() or self:getColor() + textColor = self:isHovered() and self:getHoveredTextColor() or self:getTextColor() + else + bgColor = self:getDisabledColor() + textColor = self:getDisabledTextColor() + end + + render.setColor(bgColor) + if self:getRadius() > 0 and (rTL or rTR or rBR or rBL) then + render.drawRoundedBoxEx(self:getRadius(), x, y, w, h, rTL, rTR, rBL, rBR) + else + render.drawRectFast(x, y, w, h) + end + + render.setFont(self:getFont()) + render.setColor(textColor) + render.drawSimpleText(x + w / 2 - textW / 2, y + h / 2 - textH / 2, self:getText()) +end diff --git a/koptilnya/gui/elements/checkbox.txt b/koptilnya/gui/elements/checkbox.txt new file mode 100644 index 0000000..3c74da3 --- /dev/null +++ b/koptilnya/gui/elements/checkbox.txt @@ -0,0 +1,62 @@ +--@include element.txt +--@include label.txt +--@include ../utils.txt + +require("element.txt") +require("label.txt") +require("../utils.txt") + +ECheckbox = class("ECheckbox", ELabel) + +accessorFunc(ECheckbox, "_textColor", "TextColor", Color(255, 255, 255)) +accessorFunc(ECheckbox, "_hoveredColor", "HoveredColor", Color(66, 66, 66)) +accessorFunc(ECheckbox, "_hoveredTextColor", "HoveredTextColor", Color(255, 255, 255)) +accessorFunc(ECheckbox, "_disabledColor", "DisabledColor", Color(32, 32, 32)) +accessorFunc(ECheckbox, "_disabledTextColor", "DisabledTextColor", Color(80, 80, 80)) +accessorFunc(ECheckbox, "_indent", "Indent", 8) + +function ECheckbox:initialize() + ELabel.initialize(self) + + self._checked = false + + self:setText("Checkbox") + self:setSize(200, 16) +end + +function ECheckbox:setChecked(state) + self._checked = state + + self:onChange() +end + +function ECheckbox:isChecked() + return self._checked +end + +function ECheckbox:paint() + local x, y = self:getAbsolutePos() + local w, h = self:getSize() + local textW, textH = self:getTextSize() + --[[ + local bgColor, textColor + if self:isEnabled() then + bgColor = self:isHovered() and self:getHoveredColor() or self:getColor() + textColor = self:isHovered() and self:getHoveredTextColor() or self:getTextColor() + else + bgColor = self:getDisabledColor() + textColor = self:getDisabledTextColor() + end + ]] + + render.setColor(Color(209, 209, 209)) + render.drawCircle(x, y, h / 2) + --render.drawRectOutline(x, y, h, h, -8) + + --render.setColor(Color(209, 209, 209, 0)) + --render.drawRectFast(x, y, h - 2, h - 2) + + render.setFont(self:getFont()) + render.setColor(Color(255, 255, 255)) + render.drawSimpleText(x + h + self:getIndent(), y + h / 2 - textH / 2, self:getText()) +end \ No newline at end of file diff --git a/koptilnya/gui/elements/element.txt b/koptilnya/gui/elements/element.txt new file mode 100644 index 0000000..8ffc7eb --- /dev/null +++ b/koptilnya/gui/elements/element.txt @@ -0,0 +1,359 @@ +--@include ../utils.txt +--@include ../skins/default.txt + +require("../utils.txt") +local defaultSkin = require("../skins/default.txt") + +Element = class("Element") + +accessorFunc(Element, "_x", "X", 0) +accessorFunc(Element, "_y", "Y", 0) + +function Element:initialize() + self._width = 0 + self._height = 0 + self._enabled = true + self._visible = true + self._draggable = true + self._hovered = false + self._parent = nil + self._firstChild = nil + self._prevSibling = nil + self._nextSibling = nil + self._skin = defaultSkin +end + +function Element:setWidth(width) + self._width = width + + self:performLayout(self:getSize()) +end + +function Element:getWidth() + return self._width +end + +function Element:setHeight(height) + self._height = height + + self:performLayout(self:getSize()) +end + +function Element:getHeight() + return self._height +end + +function Element:setSize(width, height) + self:setWidth(width) + self:setHeight(height) +end + +function Element:getSize() + return self:getWidth(), self:getHeight() +end + +function Element:setPos(x, y) + self:setX(x) + self:setY(y) +end + +function Element:getPos() + return self._x, self._y +end + +function Element:getAbsolutePos(x, y) + x = x == nil and self:getX() or x + self:getX() + y = y == nil and self:getY() or y + self:getY() + + if self:hasParent() then + x, y = self:getParent():getAbsolutePos(x, y) + end + + return x, y +end + +function Element:getBounds() + return self:getX(), self:getY(), self:getX() + self:getWidth(), self:getY() + self:getHeight() +end + +function Element:getAbsoluteBounds() + local aX, aY = self:getAbsolutePos() + + return aX, aY, aX + self:getWidth(), aY + self:getHeight() +end + +function Element:setEnabled(enabled) + self._enabled = enabled +end + +function Element:isEnabled() + return self._enabled +end + +function Element:setVisible(visible) + self._visible = visible +end + +function Element:isVisible() + return self._visible +end + +function Element:setDraggable(draggable) + self._draggable = draggable +end + +function Element:isDraggable() + return self._draggable +end + +function Element:isHovered() + return self._hovered +end + +function Element:setParent(parent) + checkVarClass(parent, Element) + + self._parent = parent +end + +function Element:getParent() + return self._parent +end + +function Element:hasParent() + return self:getParent() ~= nil +end + +function Element:addChild(child) + checkVarClass(child, Element) + + child:setParent(self) + child:_setSkin(self._skin) + + if not self._firstChild then + self._firstChild = child + else + local temp = self._firstChild + + while temp._nextSibling do + temp = temp._nextSibling + end + + temp._nextSibling = child + child._prevSibling = temp + end +end + +function Element:requestFocus() + --return +end + +function Element:hasFocus() + --return self._focus +end + +function Element:cursorIntersect(x, y) + --local self:getAbsoluteBounds() + local aX, aY = self:getAbsolutePos() + + if x >= aX and x <= aX + self:getWidth() and y >= aY and y <= aY + self:getHeight() then + return true + end + + return false +end + +function Element:moveToFront(child) + if child then + local next = child._nextSibling + local prev = child._prevSibling + + if prev then + prev._nextSibling = next + + if next then + next._prevSibling = prev + end + else + return + end + + child._nextSibling = self._firstChild + self._firstChild._prevSibling = child + child._prevSibling = nil + self._firstChild = child + end +end + +-- PROTECTED + +function Element:_setSkin(skin) + self._skin = skin +end + +function Element:_postEvent(eventKey, ...) + if eventKey == "THINK" then + return self:_onThink() + elseif eventKey == "PAINT" then + return self:_onPaint() + elseif eventKey == "MOUSE_PRESSED" then + return self:_onMousePressed(...) + elseif eventKey == "MOUSE_RELEASED" then + return self:_onMouseReleased(...) + elseif eventKey == "MOUSE_MOVED" then + return self:_onMouseMoved(...) + end +end + +function Element:_postEventToAll(eventKey, ...) + local temp = self._firstChild + + while temp do + local next = temp._nextSibling + + if temp:_postEvent(eventKey, ...) then + return temp + end + + temp = next + end + + return nil +end + +function Element:_postEventToAllReverse(eventKey, ...) + local next = self._nextSibling + + if next then + next:_postEventToAllReverse(eventKey, ...) + end + + self:_postEvent(eventKey, ...) + + return nil +end + +function Element:_onThink() + if self:isEnabled() then + if type(self.think) == "function" then + self:think() + end + + if self._firstChild then + self._firstChild:_postEventToAllReverse("THINK") + end + end +end + +function Element:_onPaint() + if self:isVisible() then + --[[ + if self:hasParent() then + render.enableScissorRect(self:getParent():getBounds()) + end + ]] + + self:paint() + + if self._firstChild then + self._firstChild:_postEventToAllReverse("PAINT") + end + end +end + +function Element:_onMousePressed(x, y, key, keyName) + if self:cursorIntersect(x, y) and self:isEnabled() then + local element = self:_postEventToAll("MOUSE_PRESSED", x, y, key, keyName) + + if not element then + self:onMousePressed(x, y, key, keyName) + + if self:hasParent() then + self:getParent():moveToFront(self) + end + + -- focus + end + + return true + else + -- unfocus + + return false + end +end + +function Element:_onMouseReleased(x, y, key, keyName) + if self:cursorIntersect(x, y) and self:isEnabled() then + local element = self:_postEventToAll("MOUSE_RELEASED", x, y, key, keyName) + + if not element then + self:onMouseReleased(x, y, key, keyName) + end + + return true + else + return false + end +end + +function Element:_onMouseMoved(x, y) + if self:cursorIntersect(x, y) and self:isEnabled() then + local element = self:_postEventToAll("MOUSE_MOVED", x, y) + + if not element then + if not self:isHovered() then + self._hovered = true + + self:onMouseEnter() + end + + self:onMouseMoved(x, y) + end + + return true + else + if self:isHovered() then + self._hovered = false + + self:onMouseLeave() + end + + return false + end +end + +function Element:_onButtonPressed(key, keyName) +end + +function Element:_onButtonReleased(key, keyName) +end + +-- STUB + +function Element:performLayout() +end + +function Element:paint() +end + +function Element:onMousePressed(x, y, key, keyName) +end + +function Element:onMouseReleased(x, y, key, keyName) +end + +function Element:onMouseMoved(x, y) +end + +function Element:onMouseEnter() +end + +function Element:onMouseLeave() +end + +function Element:onButtonPressed(key, keyName) +end + +function Element:onButtonReleased(key, keyName) +end \ No newline at end of file diff --git a/koptilnya/gui/elements/empty.txt b/koptilnya/gui/elements/empty.txt new file mode 100644 index 0000000..df0a2f9 --- /dev/null +++ b/koptilnya/gui/elements/empty.txt @@ -0,0 +1,7 @@ +--@include element.txt +--@include ../utils.txt + +require("element.txt") +require("../utils.txt") + +EEmpty = class("EEmpty", Element) \ No newline at end of file diff --git a/koptilnya/gui/elements/label.txt b/koptilnya/gui/elements/label.txt new file mode 100644 index 0000000..06366dd --- /dev/null +++ b/koptilnya/gui/elements/label.txt @@ -0,0 +1,58 @@ +--@include element.txt +--@include ../utils.txt + +require("element.txt") +require("../utils.txt") + +ELabel = class("ELabel", Element) + +accessorFunc(ELabel, "_color", "Color", Color(255, 255, 255)) +accessorFunc(ELabel, "_disabledColor", "DisabledColor", Color(200, 200, 200)) + +function ELabel:initialize() + Element.initialize(self) + self._text = "" + self._textWidth = 0 + self._textHeight = 0 + + self:setFont("Trebuchet18") + self:setText("Label") +end + +function ELabel:setText(text) + self._text = tostring(text) + + if self:getFont() then + render.setFont(self:getFont()) + + self._textWidth, self._textHeight = render.getTextSize(self:getText()) + end +end + +function ELabel:getText() + return self._text +end + +function ELabel:setFont(font) + self._font = font + + render.setFont(self:getFont()) + + self._textWidth, self._textHeight = render.getTextSize(self:getText()) +end + +function ELabel:getFont() + return self._font +end + +function ELabel:getTextSize() + return self._textWidth, self._textHeight +end + +function ELabel:paint() + local x, y = self:getAbsolutePos() + + render.setFont(self:getFont()) + render.setColor(self:isEnabled() and self:getColor() or self:getDisabledColor()) + render.drawSimpleText(x, y, self:getText()) +end \ No newline at end of file diff --git a/koptilnya/gui/elements/panel.txt b/koptilnya/gui/elements/panel.txt new file mode 100644 index 0000000..47e3f58 --- /dev/null +++ b/koptilnya/gui/elements/panel.txt @@ -0,0 +1,112 @@ +--@include element.txt +--@include label.txt +--@include button.txt +--@include ../utils.txt + +require("element.txt") +require("label.txt") +require("button.txt") +require("../utils.txt") + +EPanel = class("EPanel", Element) + +accessorFunc(EPanel, "_backgroundColor", "BackgroundColor", Color(23, 23, 23)) +accessorFunc(EPanel, "_parentLock", "ParentLock", false) + +function EPanel:initialize() + Element.initialize(self) + + self._minimized = false + + self.title = ELabel:new() + self.title:setPos(12, 8) + self:addChild(self.title) + + self.minimizeButton = EButton:new() + self.minimizeButton:setText("_") + self.minimizeButton:setSize(32, 32) + self.minimizeButton:setRadius(0) + self.minimizeButton:setColor(Color(0, 0, 0)) + self.minimizeButton:setHoveredColor(Color(25, 25, 25)) + self:addChild(self.minimizeButton) + + self.closeButton = EButton:new() + self.closeButton:setText("X") + self.closeButton:setSize(32, 32) + self.closeButton:setRadius(0) + self.closeButton:setColor(Color(0, 0, 0)) + self.closeButton:setHoveredColor(Color(25, 25, 25)) + self:addChild(self.closeButton) + + self:setTitle("Panel") +end + +function EPanel:setTitle(title) + self.title:setText(title) +end + +function EPanel:getTitle() + return self.title:getText() +end + +function EPanel:setMinimized(state) + self._minimized = state +end + +function EPanel:isMinimized() + return self._minimized +end + +function EPanel:onMousePressed(x, y, key, keyName) + if keyName == "MOUSE1" then + local aX, aY = self:getAbsolutePos() + + if self:isDraggable() and y < aY + 33 then + self._dragStartPos = {x - self:getX(), y - self:getY()} + end + end +end + +function EPanel:onMouseReleased(x, y, key, keyName) + if keyName == "MOUSE1" then + if self:isDraggable() then + self._dragStartPos = nil + end + end +end + +function EPanel:onMouseMoved(x, y) + if self._dragStartPos then + local targetX, targetY = x - self._dragStartPos[1], y - self._dragStartPos[2] + + if self:hasParent() and self:getParentLock() then + targetX = math.clamp(targetX, 0, 1920 - self:getWidth()) + targetY = math.clamp(targetY, 0, 1080 - self:getHeight()) + end + + self:setPos(targetX, targetY) + end +end + +function EPanel:onMouseLeave() + self._dragStartPos = nil +end + +function EPanel:performLayout(w, h) + self.closeButton:setPos(w - 33, 1) + self.minimizeButton:setPos(w - 65, 1) +end + +function EPanel:paint() + local x, y = self:getAbsolutePos() + local w, h = self:getSize() + + render.setColor(Color(255, 255, 255, 10)) + render.drawRectFast(x, y, w, h) + + render.setColor(Color(0, 0, 0)) + render.drawRectFast(x + 1, y + 1, w - 2, 32) + + render.setColor(self:getBackgroundColor()) + render.drawRectFast(x + 1, y + 33, w - 2, h - 34) +end \ No newline at end of file diff --git a/koptilnya/gui/elements/radius_mixin.txt b/koptilnya/gui/elements/radius_mixin.txt new file mode 100644 index 0000000..491c804 --- /dev/null +++ b/koptilnya/gui/elements/radius_mixin.txt @@ -0,0 +1,49 @@ +--@include ../utils.txt + +require("../utils.txt") + +local MIXIN = {} + +accessorFunc(MIXIN, "_radius", "Radius", 0) + +function MIXIN:included(target) + self._roundTopLeftCorner = false + self._roundTopRightCorner = false + self._roundBottomLeftCorner = false + self._roundBottomRightCorner = false +end + +function MIXIN:setRoundedCorners(c1, c2, c3, c4) + if c1 ~= nil and c2 ~= nil and c3 ~= nil and c4 ~= nil then + self._roundTopLeftCorner = c1 + self._roundTopRightCorner = c2 + self._roundBottomRightCorner = c3 + self._roundBottomLeftCorner = c4 + elseif c1 ~= nil and c2 ~= nil and c3 ~= nil then + self._roundTopLeftCorner = c1 + self._roundTopRightCorner = c2 + self._roundBottomRightCorner = c3 + self._roundBottomLeftCorner = c2 + elseif c1 ~= nil and c2 ~= nil then + self._roundTopLeftCorner = c1 + self._roundTopRightCorner = c2 + self._roundBottomRightCorner = c1 + self._roundBottomLeftCorner = c2 + elseif c1 ~= nil then + self._roundTopLeftCorner = c1 + self._roundTopRightCorner = c1 + self._roundBottomRightCorner = c1 + self._roundBottomLeftCorner = c1 + else + self._roundTopLeftCorner = false + self._roundTopRightCorner = false + self._roundBottomRightCorner = false + self._roundBottomLeftCorner = false + end +end + +function MIXIN:getRoundedCorners() + return self._roundTopLeftCorner, self._roundTopRightCorner, self._roundBottomRightCorner, self._roundBottomLeftCorner +end + +return MIXIN \ No newline at end of file diff --git a/koptilnya/gui/elements/root.txt b/koptilnya/gui/elements/root.txt new file mode 100644 index 0000000..94ca838 --- /dev/null +++ b/koptilnya/gui/elements/root.txt @@ -0,0 +1,5 @@ +--@include element.txt + +require("element.txt") + +ERoot = class("ERoot", Element) \ No newline at end of file diff --git a/koptilnya/gui/elements/shape.txt b/koptilnya/gui/elements/shape.txt new file mode 100644 index 0000000..d502b03 --- /dev/null +++ b/koptilnya/gui/elements/shape.txt @@ -0,0 +1,17 @@ +--@include element.txt +--@include ../utils.txt + +require("element.txt") +require("../utils.txt") + +EShape = class("EShape", Element) + +accessorFunc(EShape, "_color", "Color", Color(255, 255, 255)) + +function EShape:paint() + local x, y = self:getAbsolutePos() + local w, h = self:getSize() + + render.setColor(self:getColor()) + render.drawRectFast(x, y, w, h) +end \ No newline at end of file diff --git a/koptilnya/gui/gui.txt b/koptilnya/gui/gui.txt new file mode 100644 index 0000000..f57bc53 --- /dev/null +++ b/koptilnya/gui/gui.txt @@ -0,0 +1,81 @@ +--@include utils.txt +--@include render_devices/render_device.txt +--@include elements/root.txt +--@include skins/default.txt + +require("utils.txt") +require("render_devices/render_device.txt") +require("elements/root.txt") +local defaultSkin = require("skins/default.txt") + +GUI = class("GUI") + +function GUI:initialize(renderDevice, skin) + checkVarClass(renderDevice, RenderDevice) + + self.renderDevice = renderDevice + self._root = ERoot:new("root") + self._root:setSize(renderDevice:getSize()) + self._root:_setSkin(skin or defaultSkin) + + hook.add("inputPressed", "gui_inputPressed", function(key) + local keyName = input.getKeyName(key) + + if key >= 107 and key <= 111 then + local x, y = input.getCursorPos() + + self._root:_postEvent("MOUSE_PRESSED", x, y, key, keyName) + else + self._root:_postEvent("BUTTON_PRESSED", x, y, key, keyName) + end + end) + + hook.add("inputReleased", "gui_inputReleased", function(key) + local keyName = input.getKeyName(key) + + if key >= 107 and key <= 111 then + local x, y = input.getCursorPos() + + self._root:_postEvent("MOUSE_RELEASED", x, y, key, keyName) + else + self._root:_postEvent("BUTTON_RELEASED", x, y, key, keyName) + end + end) + + self._lastMouseX = 0 + self._lastMouseY = 0 + hook.add("think", "gui_think", function() + if input.getCursorVisible then + local x, y = input.getCursorPos() + + if x ~= self._lastMouseX or y ~= self._lastMouseY then + self._lastMouseX = x + self._lastMouseY = y + + self._root:_postEvent("MOUSE_MOVED", x, y) + end + end + + self._root:_postEvent("THINK") + end) + + renderDevice.render = function() + self._root:_postEvent("PAINT") + end +end + +function GUI:getRoot() + return self._root +end + +function GUI:add(element) + this._root:addChild(element) +end + +function GUI:setVisible(state) + self._root:setVisible(state) +end + +function GUI:isVisible() + self._root:isVisible() +end \ No newline at end of file diff --git a/koptilnya/gui/render_devices/hud.txt b/koptilnya/gui/render_devices/hud.txt new file mode 100644 index 0000000..ad9cc9b --- /dev/null +++ b/koptilnya/gui/render_devices/hud.txt @@ -0,0 +1,18 @@ +--@include render_device.txt + +require("render_device.txt") + +RenderDeviceHUD = class("RenderDeviceHUD", RenderDevice) + +function RenderDeviceHUD:initialize() + render.setHUDActive(true) + self:setSize(render.getResolution()) + + hook.add("hudshoulddraw", "gui_hudshoulddraw", function(name) + return name == "CHudGMod" or name == "CHudChat" + end) + + hook.add("postdrawhud", "gui_renderer", function() + self:render() + end) +end \ No newline at end of file diff --git a/koptilnya/gui/render_devices/render_device.txt b/koptilnya/gui/render_devices/render_device.txt new file mode 100644 index 0000000..6066cb9 --- /dev/null +++ b/koptilnya/gui/render_devices/render_device.txt @@ -0,0 +1,28 @@ +--@include ../utils.txt + +require("../utils.txt") + +RenderDevice = class("RenderDevice") + +accessorFunc(RenderDevice, "_width", "Width", 0) +accessorFunc(RenderDevice, "_height", "Height", 0) + +function RenderDevice:setHeight(height) + self._height = height +end + +function RenderDevice:getHeight() + return self._height +end + +function RenderDevice:setSize(width, height) + self:setWidth(width) + self:setHeight(height) +end + +function RenderDevice:getSize() + return self:getWidth(), self:getHeight() +end + +function RenderDevice:render() +end \ No newline at end of file diff --git a/koptilnya/gui/render_devices/screen.txt b/koptilnya/gui/render_devices/screen.txt new file mode 100644 index 0000000..2a66827 --- /dev/null +++ b/koptilnya/gui/render_devices/screen.txt @@ -0,0 +1,13 @@ +--@include render_device.txt + +require("render_device.txt") + +RenderDeviceScreen = class("RenderDeviceScreen", RenderDevice) + +function RenderDeviceScreen:initialize() + self:setSize(512, 512) + + hook.add("render", "gui_renderer", function() + self:render() + end) +end \ No newline at end of file diff --git a/koptilnya/gui/skins/default.txt b/koptilnya/gui/skins/default.txt new file mode 100644 index 0000000..e975c4f --- /dev/null +++ b/koptilnya/gui/skins/default.txt @@ -0,0 +1,5 @@ +local SKIN = {} + +-- :( + +return SKIN \ No newline at end of file diff --git a/koptilnya/libs/render.txt b/koptilnya/libs/render.txt new file mode 100644 index 0000000..e69de29 diff --git a/koptilnya/libs/utils.txt b/koptilnya/libs/utils.txt new file mode 100644 index 0000000..e52ff53 --- /dev/null +++ b/koptilnya/libs/utils.txt @@ -0,0 +1,11 @@ +function checkVarClass(var, class, message) + if type(var) ~= "table" or var["class"] == nil or not var:isInstanceOf(class) then + throw(message == nil and "Wrong variable class." or message, 1, true) + end +end + +function accessorFunc(tbl, varName, name, defaultValue) + tbl[varName] = defaultValue + tbl["get" .. name] = function(self) return self[varName] end + tbl["set" .. name] = function(self, value) self[varName] = value end +end \ No newline at end of file diff --git a/koptilnya/mesh_loader/base_entity.txt b/koptilnya/mesh_loader/base_entity.txt new file mode 100644 index 0000000..63beaf8 --- /dev/null +++ b/koptilnya/mesh_loader/base_entity.txt @@ -0,0 +1,5 @@ +BaseEntity = class("BaseEntity") + +function BaseEntity:initialize() + +end \ No newline at end of file diff --git a/koptilnya/mesh_loader/builder.txt b/koptilnya/mesh_loader/builder.txt new file mode 100644 index 0000000..b6b8783 --- /dev/null +++ b/koptilnya/mesh_loader/builder.txt @@ -0,0 +1,153 @@ +local MODEL_PLACEHOLDER = "models/holograms/cube.mdl" +local BUNDLE_SIZE = 30 +local SEND_DELAY = 2 + +MeshBuilder = class("MeshBuilder") + +function MeshBuilder:initialize() + self._objects = {} + self._bundle = {} + + if CLIENT then + self._meshData = {} + + net.receive("sendHolograms", function(len) + local hasNext = net.readBit() + + while hasNext == 1 do + local key = net.readString() + + net.readEntity(function(ent) + if not self._objects[key] then + + local holo = ent:toHologram() + + if self._meshData[key] then + holo:setMesh(self._meshData[key]) + holo:setRenderBounds(Vector(-200), Vector(200)) + end + + self._objects[key] = holo + end + end) + + hasNext = net.readBit() + end + end) + else + + net.receive("sendObjects", function(len, ply) + local hasNext = net.readBit() + + while hasNext == 1 do + local key = net.readString() + local pos = net.readVector() + local ang = net.readAngle() + local scale = net.readVector() + local color = net.readColor() + local mat = net.readString() + local parent = net.readEntity() + + if not self._objects[key] then + if isValid(parent) then + pos = parent:localToWorld(pos) + ang = parent:localToWorldAngles(ang) + end + + local holo = holograms.create(pos, ang, MODEL_PLACEHOLDER, scale) + holo:setColor(color) + holo:setMaterial(mat) + holo:setParent(parent) + + self._objects[key] = holo + end + + if not self._bundle[key] then + self._bundle[key] = self._objects[key] + end + + hasNext = net.readBit() + end + + net.start("sendHolograms") + for k, v in pairs(self._bundle) do + if isValid(v) and type(v) == "Hologram" then + net.writeBit(1) + net.writeString(k) + net.writeEntity(v) + end + end + net.writeBit(0) + net.send(ply) + + table.empty(self._bundle) + end) + end +end + +if CLIENT then + function MeshBuilder:setMeshData(meshData) + self._meshData = meshData + end + + function MeshBuilder:setup(key, pos, ang, scale, color, mat, parent) + if not self._objects[key] and not self._bundle[key] and self._meshData[key] then + self._bundle[key] = { + pos = pos, + ang = ang, + scale = scale, + color = color, + mat = mat, + parent = isValid(parent) and parent or chip() + } + end + end + + function MeshBuilder:setupAll(pos, ang, scale, color, mat, parent) + for _, v in pairs(table.getKeys(self._meshData)) do + self:setup(v, pos, ang, scale, color, mat, parent) + end + end + + function MeshBuilder:build() + local function send(objects) + net.start("sendObjects") + for k, v in pairs(objects) do + net.writeBit(1) + net.writeString(k) + net.writeVector(v.pos) + net.writeAngle(v.ang) + net.writeVector(v.scale) + net.writeColor(v.color) + net.writeString(v.mat) + net.writeEntity(v.parent) + end + net.writeBit(0) + net.send() + end + + local bundleKeys = table.getKeys(self._bundle) + if #bundleKeys > BUNDLE_SIZE then + local i = 1 + + timer.create("send", SEND_DELAY, math.ceil(#bundleKeys / BUNDLE_SIZE), function() + local from = (i - 1) * BUNDLE_SIZE + 1 + local objects = {} + + for _, v in pairs({ unpack(bundleKeys, from, from + BUNDLE_SIZE - 1) }) do + objects[v] = self._bundle[v] + end + + send(objects) + + if i < math.ceil(#bundleKeys / BUNDLE_SIZE) then + i = i + 1 + else + table.empty(self._bundle) + end + end) + else + send(self._bundle) + end + end +end \ No newline at end of file diff --git a/koptilnya/mesh_loader/parser.txt b/koptilnya/mesh_loader/parser.txt new file mode 100644 index 0000000..b20011e --- /dev/null +++ b/koptilnya/mesh_loader/parser.txt @@ -0,0 +1,36 @@ +local MAX_QUOTA = 0.75 + +Parser = class("Parser") + +function Parser:initialize(link) + if CLIENT then + local triangles = mesh.trianglesLeft() + local createFromObjCoroutine = coroutine.create(function(objData) + self:OnLoaded(objData, mesh.createFromObj(objData, true)) + end) + + print("Getting file...") + http.get(link, function(objData) + local loadMesh = coroutine.wrap(function() + self.meshData = mesh.createFromObj(objData, true) + + return true + end) + + print("File received, start parsing...") + hook.add("think", "loadingMesh", function() + while quotaAverage() < quotaMax() * MAX_QUOTA do + if loadMesh() then + self:onLoaded(objData, self.meshData, triangles - mesh.trianglesLeft()) + hook.remove("think", "loadingMesh") + + return + end + end + end) + end) + end +end + +function Parser:onLoaded(objData, meshData, usedTriangles) +end \ No newline at end of file diff --git a/koptilnya/rpc.txt b/koptilnya/rpc.txt new file mode 100644 index 0000000..a161c98 --- /dev/null +++ b/koptilnya/rpc.txt @@ -0,0 +1,32 @@ +--@name RPC +--@author Opti1337 +--@shared + +RPC = {} + +function RPC.add(name, cb) + net.receive(name, function() + local result = {} + + for i = 1, net.readInt(8) do + table.insert(result, net.readType()) + end + + if CLIENT then + cb(unpack(result)) + else + RPC.start(name, find.allPlayers(), unpack(result)) + end + end) +end + +function RPC.start(name, target, ...) + net.start(name) + local args = {...} + + net.writeInt(#args, 8) + for _, v in pairs(args) do + net.writeType(v) + end + net.send(target) +end \ No newline at end of file