removed magic number for fake isometric thing

export ^

require "star"
gamera = require "lib/gamera/gamera"

class SpacebaseView
    new: (@spacebase) =>
        @size = @spacebase.totalSize()
        @canvas = love.graphics.newCanvas(@size, @size)
        @cam = gamera.new(-@size/2, -@size/2, 2 * @size, 2 * @size)
        @cam\setPosition(@size/2, @size/2)
        @cam\setAngle(math.pi/4)
        @squishFactor = 2 -- fake isometric thing

        @offset_speed = 500  -- px/s
        @zoom_rate = 0.7
        @rotationspeed = 1

        @starField = {}
        number_of_stars = 200
        for i=1,number_of_stars
            table.insert(@starField, Star())

    update: (dt) =>
        cam_x, cam_y = @cam\getPosition()
        cam_zoom = @cam\getScale()
        cam_angle = @cam\getAngle()
        if love.keyboard.isDown("down")
            cam_x -= @offset_speed * dt * math.sin(cam_angle)
            cam_y += @offset_speed * dt * math.cos(cam_angle)
        if love.keyboard.isDown("up")
            cam_x += @offset_speed * dt * math.sin(cam_angle)
            cam_y -= @offset_speed * dt * math.cos(cam_angle)
        if love.keyboard.isDown("right")
            cam_x += @offset_speed * dt * math.cos(cam_angle)
            cam_y += @offset_speed * dt * math.sin(cam_angle)
        if love.keyboard.isDown("left")
            cam_x -= @offset_speed * dt * math.cos(cam_angle)
            cam_y -= @offset_speed * dt * math.sin(cam_angle)
        @cam\setPosition(cam_x, cam_y)
        if love.keyboard.isDown("i")
            @cam\setScale(cam_zoom + cam_zoom * @zoom_rate * dt)
        if love.keyboard.isDown("o")
            @cam\setScale(cam_zoom - cam_zoom * @zoom_rate * dt)
        if love.keyboard.isDown("r")
            @cam\setAngle(cam_angle + @rotationspeed * dt)

    draw: =>
        @\draw_starfield()
        love.graphics.scale(1, 1 / @squishFactor)
        -- draw spacebase (rotated and squished)
        @cam\draw(@spacebase\draw)
        -- draw entities (minions and items) (un-rotated and un-squished)
        love.graphics.scale(1, @squishFactor)
        for minion in *@spacebase.crew
            sx, sy = @cam\toScreen(minion.x, minion.y)
            sy /= @squishFactor
            love.graphics.push()
            scale = @cam\getScale()
            love.graphics.scale(scale, scale)
            love.graphics.translate(sx / scale, sy / scale)
            minion\draw()
            love.graphics.pop()

        for room in *@spacebase.rooms
            for tile in *room.tiles
                item = tile.itemContained
                if item
                    {wx, wy} = @spacebase\tileToWorld(tile.row, tile.col)
                    sx, sy = @cam\toScreen(wx, wy)
                    sy /= @squishFactor -- account for squishiness
                    love.graphics.push()
                    scale = @cam\getScale()
                    love.graphics.scale(scale, scale)
                    love.graphics.translate(sx / scale, sy / scale)
                    item\draw()
                    love.graphics.pop()

    draw_starfield: =>
        spaceColor = {14, 17, 23}
        w_x, w_y = @cam\toScreen(0, 0)
        love.graphics.setColor(spaceColor)
        love.graphics.rectangle("fill", 0, 0, wScr(), hScr())
        for star in *@starField
            star\draw(w_x, w_y)

    -- draw_spacebase: =>
    --     w, h = wScr(), hScr()
    --     @canvas\clear(0, 0, 0, 0) -- clear to transparent
    --     love.graphics.setCanvas(@canvas)
    --     @spacebase\draw()
    --     love.graphics.setCanvas()
    --     love.graphics.scale(@zoom, @zoom)
    --     translate_x = @offset_center_x + w / (2 * @zoom)
    --     translate_y = @offset_center_y + h / (2 * @zoom)
    --     love.graphics.translate(translate_x, translate_y)
    --     -- love.graphics.scale(1, 0.5)
    --     -- love.graphics.rotate(math.pi/4 + @rotation)
    --     -- love.graphics.circle("fill", 0, 0, 10)
    --     love.graphics.setColor(255, 255, 255)
    --     love.graphics.draw(@canvas, -@size / (2 * @zoom), -@size / (2 * @zoom))

    keyreleased: (key) =>

    coordinatesInWorld: (x, y) =>
        world_x, world_y = @cam\toWorld(x, @squishFactor * y)
        return {world_x, world_y}

export ^

require "star"
gamera = require "lib/gamera/gamera"

class SpacebaseView
    new: (@spacebase) =>
        @size = @spacebase.totalSize()
        @canvas = love.graphics.newCanvas(@size, @size)
        @cam = gamera.new(-@size/2, -@size/2, 2 * @size, 2 * @size)
        @cam\setPosition(@size/2, @size/2)
        @cam\setAngle(math.pi/4)

        @offset_speed = 500  -- px/s
        @zoom_rate = 0.7
        @rotationspeed = 1

        @starField = {}
        number_of_stars = 200
        for i=1,number_of_stars
            table.insert(@starField, Star())

    update: (dt) =>
        cam_x, cam_y = @cam\getPosition()
        cam_zoom = @cam\getScale()
        cam_angle = @cam\getAngle()
        if love.keyboard.isDown("down")
            cam_x -= @offset_speed * dt * math.sin(cam_angle)
            cam_y += @offset_speed * dt * math.cos(cam_angle)
        if love.keyboard.isDown("up")
            cam_x += @offset_speed * dt * math.sin(cam_angle)
            cam_y -= @offset_speed * dt * math.cos(cam_angle)
        if love.keyboard.isDown("right")
            cam_x += @offset_speed * dt * math.cos(cam_angle)
            cam_y += @offset_speed * dt * math.sin(cam_angle)
        if love.keyboard.isDown("left")
            cam_x -= @offset_speed * dt * math.cos(cam_angle)
            cam_y -= @offset_speed * dt * math.sin(cam_angle)
        @cam\setPosition(cam_x, cam_y)
        if love.keyboard.isDown("i")
            @cam\setScale(cam_zoom + cam_zoom * @zoom_rate * dt)
        if love.keyboard.isDown("o")
            @cam\setScale(cam_zoom - cam_zoom * @zoom_rate * dt)
        if love.keyboard.isDown("r")
            @cam\setAngle(cam_angle + @rotationspeed * dt)

    draw: =>
        @\draw_starfield()
        love.graphics.scale(1, 0.5) -- fake-isometric squish
        -- draw spacebase (rotated and squished)
        @cam\draw(@spacebase\draw)
        -- draw entities (minions and items) (un-rotated and un-squished)
        love.graphics.scale(1, 2)
        for minion in *@spacebase.crew
            sx, sy = @cam\toScreen(minion.x, minion.y)
            sy /= 2 -- account for squishiness
            love.graphics.push()
            scale = @cam\getScale()
            love.graphics.scale(scale, scale)
            love.graphics.translate(sx / scale, sy / scale)
            minion\draw()
            love.graphics.pop()

        for room in *@spacebase.rooms
            for tile in *room.tiles
                item = tile.itemContained
                if item
                    {wx, wy} = @spacebase\tileToWorld(tile.row, tile.col)
                    sx, sy = @cam\toScreen(wx, wy)
                    sy /= 2 -- account for squishiness
                    love.graphics.push()
                    scale = @cam\getScale()
                    love.graphics.scale(scale, scale)
                    love.graphics.translate(sx / scale, sy / scale)
                    item\draw()
                    love.graphics.pop()

    draw_starfield: =>
        spaceColor = {14, 17, 23}
        w_x, w_y = @cam\toScreen(0, 0)
        love.graphics.setColor(spaceColor)
        love.graphics.rectangle("fill", 0, 0, wScr(), hScr())
        for star in *@starField
            star\draw(w_x, w_y)

    -- draw_spacebase: =>
    --     w, h = wScr(), hScr()
    --     @canvas\clear(0, 0, 0, 0) -- clear to transparent
    --     love.graphics.setCanvas(@canvas)
    --     @spacebase\draw()
    --     love.graphics.setCanvas()
    --     love.graphics.scale(@zoom, @zoom)
    --     translate_x = @offset_center_x + w / (2 * @zoom)
    --     translate_y = @offset_center_y + h / (2 * @zoom)
    --     love.graphics.translate(translate_x, translate_y)
    --     -- love.graphics.scale(1, 0.5)
    --     -- love.graphics.rotate(math.pi/4 + @rotation)
    --     -- love.graphics.circle("fill", 0, 0, 10)
    --     love.graphics.setColor(255, 255, 255)
    --     love.graphics.draw(@canvas, -@size / (2 * @zoom), -@size / (2 * @zoom))

    keyreleased: (key) =>

    coordinatesInWorld: (x, y) =>
        world_x, world_y = @cam\toWorld(x, 2 * y)
        return {world_x, world_y}


utf8: add more maps

utf8: add more maps

html2unicode = require'html'
math = require'math'

an = [[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,.?!"'`()[]{}<>&_]]
charmaps = {
ci: 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ⓪①②③④⑤⑥⑦⑧⑨'
bl: '𝔄𝔅ℭ𝔇𝔈𝔉𝔊ℌℑ𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔ℜ𝔖𝔗𝔘𝔙𝔚𝔛𝔜ℨ𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷'
ud: [[∀BƆDƎℲפHIſK˥WNOԀQRS┴∩ΛMX⅄Zɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz0ƖᄅƐㄣϛ9ㄥ86'˙¿¡,,,)(][}{><⅋‾]]
nc: [[🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩⓿]]
sq: [[🄰🄱🄲🄳🄴🄵🄶🄷🄸🄹🄺🄻🄼🄽🄾🄿🅀🅁🅂🅃🅄🅅🅆🅇🅈🅉🄰🄱🄲🄳🄴🄵🄶🄷🄸🄹🄺🄻🄼🄽🄾🄿🅀🅁🅂🅃🅄🅅🅆🅇🅈🅉0123456789,⊡]]
ns: [[🅰🅱🅲🅳🅴🅵🅶🅷🅸🅹🅺🅻🅼🅽🅾🅿🆀🆁🆂🆃🆄🆅🆆🆇🆈🆉🅰🅱🅲🅳🅴🅵🅶🅷🅸🅹🅺🅻🅼🅽🅾🅿🆀🆁🆂🆃🆄🆅🆆🆇🆈🆉]]
ds: [[𝔸𝔹ℂ𝔻𝔼𝔽𝔾ℍ𝕀𝕁𝕂𝕃𝕄ℕ𝕆ℙℚℝ𝕊𝕋𝕌𝕍𝕎𝕏𝕐ℤ𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡]]
bo: [[𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗]]
bi: [[𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛0123456789]]
bs: [[𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃]]
pt: [[ ⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵0⑴⑵⑶⑷⑸⑹⑺⑻⑼]]
}
codepoints = (str) ->
  str\gmatch("[%z\1-\127\194-\244][\128-\191]*")

-- Construct a table which can be used for lookup replacement later
-- Iterate over normal ascii and find counterparts in the weirdo strings as substrings
maps = {}
for charmap, chars in pairs charmaps
  i = 1
  maps[charmap] = {}
  for uchar in string.gfind(chars, "([%z\1-\127\194-\244][\128-\191]*)")
    maps[charmap][an\sub(i,i)] = uchar
    i = i +1

unichr = (n) ->
  html2unicode('&#x%x;'\format(n))

wireplace = (offset, arg) ->
    s = arg or ''
    t = {}
    for i = 1, #s
      bc = string.byte(s, i, i)
      -- Replace space width ideographic space for fullwidth offset
      if bc == 32 and offset == 0xFEE0
        t[#t + 1] = '\227\128\128'
      elseif bc == 32
        t[#t + 1] = ' '
      elseif bc < 0x80 then
        t[#t + 1] = html2unicode("&#" .. (offset + bc) .. ";")
      else
        t[#t + 1] = s\sub(i, i)

    table.concat(t, "")

remap = (map, s) ->
  table.concat [map[s\sub(i,i)] or s\sub(i,i) for i=1, #s], ''

zalgo = (text, intensity=50) ->
  zalgo_chars = {}
  for i=0x0300, 0x036f
    zalgo_chars[i-0x2ff] = unichr(i)

  zalgo_chars[#zalgo_chars + 1] = unichr(0x0488)
  zalgo_chars[#zalgo_chars + 0] = unichr(0x0489)

  zalgoized = {}
  for letter in codepoints(text)
    zalgoized[#zalgoized + 1] = letter
    zalgo_num = math.random(1, intensity)
    for i=1, zalgo_num
      zalgoized[#zalgoized + 1] = zalgo_chars[math.random(1, #zalgo_chars)]
  table.concat(zalgoized)

PRIVMSG:
  '^%pwide (.+)$': (source, destination, arg) =>
    say wireplace(0xFEE0, arg)
  '^%pblackletter (.+)$': (source, destination, arg) =>
    say remap(maps.bl, arg)
  '^%pcircled (.+)$': (source, destination, arg) =>
    say remap(maps.ci, arg)
  '^%pzalgo (.+)$': (source, destination, arg) =>
    say zalgo(arg, 7)
  '^%pupsidedown (.+)$': (source, destination, arg) =>
    say remap(maps.ud, arg)
  '^%pflip (.+)$': (source, destination, arg) =>
    say remap(maps.ud, arg)
  '^%pparanthesized (.+)$': (source, destination, arg) =>
    say remap(maps.pt, arg)
  '^%pnegcircle (.+)$': (source, destination, arg) =>
    say remap(maps['nc'], arg)
  '^%psquare (.+)$': (source, destination, arg) =>
    say remap(maps.sq, arg)
  '^%pnegsquare (.+)$': (source, destination, arg) =>
    say remap(maps.ns, arg)
  '^%pdoublestruck (.+)$': (source, destination, arg) =>
    say remap(maps.ds, arg)
  '^%pubold (.+)$': (source, destination, arg) =>
    say remap(maps.bo, arg)
  '^%pbolditalic (.+)$': (source, destination, arg) =>
    say remap(maps.bi, arg)
  '^%pboldscript (.+)$': (source, destination, arg) =>
    say remap(maps.bs, arg)

html2unicode = require'html'
math = require'math'

an = [[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,.?!"'`()[]{}<>&_]]
ci = 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ⓪①②③④⑤⑥⑦⑧⑨'
bl = '𝔄𝔅ℭ𝔇𝔈𝔉𝔊ℌℑ𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔ℜ𝔖𝔗𝔘𝔙𝔚𝔛𝔜ℨ𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷'
ud = [[∀BƆDƎℲפHIſK˥WNOԀQRS┴∩ΛMX⅄Zɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz0ƖᄅƐㄣϛ9ㄥ86'˙¿¡,,,)(][}{><⅋‾]]

an2ci = {}
-- Circled letters are 3 bytes, just use sub string
for i=1, #an
  f = i*3+1-3
  t = i*3
  an2ci[an\sub(i,i)] = ci\sub(f, t)

an2bl = {}
i=1
-- Since blackletters have varying byte length, use the common lua pattern to find multibyte chars
for uchar in string.gfind(bl, "([%z\1-\127\194-\244][\128-\191]*)")
  an2bl[an\sub(i,i)] = uchar
  i = i +1

an2ud = {}
i=1
for uchar in string.gfind(ud, "([%z\1-\127\194-\244][\128-\191]*)")
  an2ud[an\sub(i,i)] = uchar
  i = i +1

codepoints = (str) ->
  str\gmatch("[%z\1-\127\194-\244][\128-\191]*")

unichr = (n) ->
  html2unicode('&#x%x;'\format(n))

wireplace = (offset, arg) ->
    s = arg or ''
    t = {}
    for i = 1, #s
      bc = string.byte(s, i, i)
      -- Replace space width ideographic space for fullwidth offset
      if bc == 32 and offset == 0xFEE0
        t[#t + 1] = '\227\128\128'
      elseif bc == 32
        t[#t + 1] = ' '
      elseif bc < 0x80 then
        t[#t + 1] = html2unicode("&#" .. (offset + bc) .. ";")
      else
        t[#t + 1] = s\sub(i, i)

    table.concat(t, "")

remap = (map, s) ->
  table.concat [map[s\sub(i,i)] or s\sub(i,i) for i=1, #s], ''

zalgo = (text, intensity=50) ->
  zalgo_chars = {}
  for i=0x0300, 0x036f
    zalgo_chars[i-0x2ff] = unichr(i)

  zalgo_chars[#zalgo_chars + 1] = unichr(0x0488)
  zalgo_chars[#zalgo_chars + 0] = unichr(0x0489)

  zalgoized = {}
  for letter in codepoints(text)
    zalgoized[#zalgoized + 1] = letter
    zalgo_num = math.random(1, intensity)
    for i=1, zalgo_num
      zalgoized[#zalgoized + 1] = zalgo_chars[math.random(1, #zalgo_chars)]
  table.concat(zalgoized)

PRIVMSG:
  '^%pwide (.+)$': (source, destination, arg) =>
    say wireplace(0xFEE0, arg)
  '^%pblackletter (.+)$': (source, destination, arg) =>
    say remap(an2bl, arg)
  '^%pcircled (.+)$': (source, destination, arg) =>
    say remap(an2ci, arg)
  '^%pzalgo (.+)$': (source, destination, arg) =>
    say zalgo(arg, 10)
  '^%pupsidedown (.+)$': (source, destination, arg) =>
    say remap(an2ud, arg)
  '^%pflip (.+)$': (source, destination, arg) =>
    say remap(an2ud, arg)


Fixed lua errors

Fixed lua errors

--
-- Copyright (C) 2017 DBot
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
--     http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--

timer.Create 'PPM2.ModelChecks', 1, 0, ->
    for ply in *player.GetAll()
        ply.__cachedIsPony = ply\IsPony()

        if ply.__cachedIsPony
            for wep in *ply\GetWeapons()
                continue if not wep
                wep\SetNoDraw(true)
                wep.__ppm2_weapon_hit = true
        else
            for wep in *ply\GetWeapons()
                continue if not wep
                continue if not wep.__ppm2_weapon_hit
                wep\SetNoDraw(false)
                ply.__ppm2_weapon_hit = false

PPM2.PostDrawOpaqueRenderables = (a, b) ->
    return if a or b
    lply = LocalPlayer()

    for ply in *player.GetAll()
        alive = ply\Alive()
        ply.__ppm2_last_dead = RealTime() + 2 if not alive
        if ply.__cachedIsPony
            if ply\GetPonyData() and not alive
                data = ply\GetPonyData()
                rag = ply\GetRagdollEntity()
                if IsValid(rag)
                    rag\SetNoDraw(true)
                    renderController = data\GetRenderController()
                    data\DoRagdollMerge()
                    if renderController
                        renderController\PreDraw(rag)
                        rag\DrawModel()
                        renderController\PostDraw(rag)

PPM2.PrePlayerDraw = =>
    return unless @GetPonyData()
    @__cachedIsPony = @IsPony()
    return if not @__cachedIsPony
    return if @__ppm2_last_draw == FrameNumber()
    @__ppm2_last_draw = FrameNumber()
    return if @IsDormant()
    @__ppm2_last_dead = @__ppm2_last_dead or 0
    return if @__ppm2_last_dead > RealTime()
    data = @GetPonyData()
    renderController = data\GetRenderController()
    status = renderController\PreDraw() if renderController
    return status if status ~= nil
PPM2.PostPlayerDraw = =>
    return unless @GetPonyData()
    return unless @__cachedIsPony
    data = @GetPonyData()
    renderController = data\GetRenderController()
    renderController\PostDraw() if renderController

hook.Add 'PrePlayerDraw', 'PPM2.PlayerDraw', PPM2.PrePlayerDraw, -2
hook.Add 'PostPlayerDraw', 'PPM2.PostPlayerDraw', PPM2.PostPlayerDraw, -2
hook.Add 'PostDrawOpaqueRenderables', 'PPM2.PostDrawOpaqueRenderables', PPM2.PostDrawOpaqueRenderables, 2
hook.Add 'RenderScreenspaceEffects', 'PPM2.RenderScreenspaceEffects', ->
    self = LocalPlayer()

    if @__cachedIsPony and @GetPonyData() and @Alive()
        @GetPonyData()\GetRenderController()\DrawLegs()

SHOULD_DRAW_VIEWMODEL = CreateConVar('cl_ppm2_draw_hands', '1', {FCVAR_ARCHIVE}, 'Should draw hooves as viewmodel')

hook.Add 'PreDrawPlayerHands', 'PPM2.ViewModel', (arms = NULL, viewmodel = NULL, ply = LocalPlayer(), weapon = NULL) ->
    return true unless SHOULD_DRAW_VIEWMODEL\GetBool()
    return unless IsValid(arms)
    return unless ply.__cachedIsPony
    return unless ply\Alive()
    data = ply\GetPonyData()
    return unless data
    status = data\GetRenderController()\PreDrawArms(arms)
    return status if status ~= nil
    arms.__ppm2_draw = true

hook.Add 'PostDrawPlayerHands', 'PPM2.ViewModel', (arms = NULL, viewmodel = NULL, ply = LocalPlayer(), weapon = NULL) ->
    return unless IsValid(arms)
    return unless arms.__ppm2_draw
    data = ply\GetPonyData()
    return unless data
    data\GetRenderController()\PostDrawArms(arms)
    arms.__ppm2_draw = false

PlayerRespawn = ->
    ent = net.ReadEntity()
    return if not IsValid(ent)
    return if not ent\GetPonyData()
    ent\GetPonyData()\PlayerRespawn()

PlayerDeath = ->
    ent = net.ReadEntity()
    return if not IsValid(ent)
    return if not ent\GetPonyData()
    ent\GetPonyData()\PlayerDeath()

lastDataSend = 0
lastDataReceived = 0
net.Receive 'PPM2.RequestPonyData', ->
    return if lastDataReceived > RealTime()
    lastDataReceived = RealTime() + 10
    RunConsoleCommand('ppm2_reload')

net.Receive 'PPM2.PlayerRespawn', PlayerRespawn
net.Receive 'PPM2.PlayerDeath', PlayerDeath

concommand.Add 'ppm2_require', ->
    net.Start('PPM2.Require')
    net.SendToServer()
    PPM2.Message 'Requesting pony data...'

concommand.Add 'ppm2_reload', ->
    return if lastDataSend > RealTime()
    lastDataSend = RealTime() + 10
    instance = PPM2.GetMainData()
    newData = instance\CreateNetworkObject()
    newData\Create()
    instance\SetNetworkData(newData)
    PPM2.Message 'Sending pony data to server...'

hook.Add 'KeyPress', 'PPM2.RequireData', ->
    hook.Remove 'KeyPress', 'PPM2.RequireData'
    RunConsoleCommand('ppm2_reload')
    timer.Simple 3, -> RunConsoleCommand('ppm2_require')

PPM_HINT_COLOR_FIRST = Color(255, 255, 255)
PPM_HINT_COLOR_SECOND = Color(0, 0, 0)

hook.Add 'HUDPaint', 'PPM2.EditorStatus', ->
    lply = LocalPlayer()
    lpos = lply\EyePos()
    for ply in *player.GetAll()
        if ply ~= lply
            if ply\GetNWBool('PPM2.InEditor')
                pos = ply\EyePos()
                dist = pos\Distance(lpos)
                if dist < 250
                    pos.z += 10
                    alpha = math.Clamp(1 - dist / 250, 0.1, 1)
                    {:x, :y} = pos\ToScreen()
                    draw.DrawText('In PPM/2 Editor', 'HudHintTextLarge', x + 1, y + 1, PPM_HINT_COLOR_SECOND, TEXT_ALIGN_CENTER)
                    draw.DrawText('In PPM/2 Editor', 'HudHintTextLarge', x, y, PPM_HINT_COLOR_FIRST, TEXT_ALIGN_CENTER)

concommand.Add 'ppm2_cleanup', ->
    for ent in *ents.GetAll()
        if ent.isPonyPropModel and not IsValid(ent.manePlayer)
            ent\Remove()
    PPM2.Message('All unused models were removed')

timer.Create 'PPM2.ModelCleanup', 60, 0, ->
    for ent in *ents.GetAll()
        if ent.isPonyPropModel and not IsValid(ent.manePlayer)
            ent\Remove()

--
-- Copyright (C) 2017 DBot
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
--     http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--

timer.Create 'PPM2.ModelChecks', 1, 0, ->
    for ply in *player.GetAll()
        ply.__cachedIsPony = ply\IsPony()

        if ply.__cachedIsPony
            for wep in *ply\GetWeapons()
                wep\SetNoDraw(true)
                wep.__ppm2_weapon_hit = true
        else
            for wep in *ply\GetWeapons()
                continue if not wep.__ppm2_weapon_hit
                wep\SetNoDraw(false)
                ply.__ppm2_weapon_hit = false

PPM2.PostDrawOpaqueRenderables = (a, b) ->
    return if a or b
    lply = LocalPlayer()

    for ply in *player.GetAll()
        alive = ply\Alive()
        ply.__ppm2_last_dead = RealTime() + 2 if not alive
        if ply.__cachedIsPony
            if ply\GetPonyData() and not alive
                data = ply\GetPonyData()
                rag = ply\GetRagdollEntity()
                if IsValid(rag)
                    rag\SetNoDraw(true)
                    renderController = data\GetRenderController()
                    data\DoRagdollMerge()
                    if renderController
                        renderController\PreDraw(rag)
                        rag\DrawModel()
                        renderController\PostDraw(rag)

PPM2.PrePlayerDraw = =>
    return unless @GetPonyData()
    @__cachedIsPony = @IsPony()
    return if not @__cachedIsPony
    return if @__ppm2_last_draw == FrameNumber()
    @__ppm2_last_draw = FrameNumber()
    return if @IsDormant()
    @__ppm2_last_dead = @__ppm2_last_dead or 0
    return if @__ppm2_last_dead > RealTime()
    data = @GetPonyData()
    renderController = data\GetRenderController()
    status = renderController\PreDraw() if renderController
    return status if status ~= nil
PPM2.PostPlayerDraw = =>
    return unless @GetPonyData()
    return unless @__cachedIsPony
    data = @GetPonyData()
    renderController = data\GetRenderController()
    renderController\PostDraw() if renderController

hook.Add 'PrePlayerDraw', 'PPM2.PlayerDraw', PPM2.PrePlayerDraw, -2
hook.Add 'PostPlayerDraw', 'PPM2.PostPlayerDraw', PPM2.PostPlayerDraw, -2
hook.Add 'PostDrawOpaqueRenderables', 'PPM2.PostDrawOpaqueRenderables', PPM2.PostDrawOpaqueRenderables, 2
hook.Add 'RenderScreenspaceEffects', 'PPM2.RenderScreenspaceEffects', ->
    self = LocalPlayer()

    if @__cachedIsPony and @GetPonyData() and @Alive()
        @GetPonyData()\GetRenderController()\DrawLegs()

SHOULD_DRAW_VIEWMODEL = CreateConVar('cl_ppm2_draw_hands', '1', {FCVAR_ARCHIVE}, 'Should draw hooves as viewmodel')

hook.Add 'PreDrawPlayerHands', 'PPM2.ViewModel', (arms = NULL, viewmodel = NULL, ply = LocalPlayer(), weapon = NULL) ->
    return true unless SHOULD_DRAW_VIEWMODEL\GetBool()
    return unless IsValid(arms)
    return unless ply.__cachedIsPony
    return unless ply\Alive()
    data = ply\GetPonyData()
    return unless data
    status = data\GetRenderController()\PreDrawArms(arms)
    return status if status ~= nil
    arms.__ppm2_draw = true

hook.Add 'PostDrawPlayerHands', 'PPM2.ViewModel', (arms = NULL, viewmodel = NULL, ply = LocalPlayer(), weapon = NULL) ->
    return unless IsValid(arms)
    return unless arms.__ppm2_draw
    data = ply\GetPonyData()
    return unless data
    data\GetRenderController()\PostDrawArms(arms)
    arms.__ppm2_draw = false

PlayerRespawn = ->
    ent = net.ReadEntity()
    return if not IsValid(ent)
    return if not ent\GetPonyData()
    ent\GetPonyData()\PlayerRespawn()

PlayerDeath = ->
    ent = net.ReadEntity()
    return if not IsValid(ent)
    return if not ent\GetPonyData()
    ent\GetPonyData()\PlayerDeath()

lastDataSend = 0
lastDataReceived = 0
net.Receive 'PPM2.RequestPonyData', ->
    return if lastDataReceived > RealTime()
    lastDataReceived = RealTime() + 10
    RunConsoleCommand('ppm2_reload')

net.Receive 'PPM2.PlayerRespawn', PlayerRespawn
net.Receive 'PPM2.PlayerDeath', PlayerDeath

concommand.Add 'ppm2_require', ->
    net.Start('PPM2.Require')
    net.SendToServer()
    PPM2.Message 'Requesting pony data...'

concommand.Add 'ppm2_reload', ->
    return if lastDataSend > RealTime()
    lastDataSend = RealTime() + 10
    instance = PPM2.GetMainData()
    newData = instance\CreateNetworkObject()
    newData\Create()
    instance\SetNetworkData(newData)
    PPM2.Message 'Sending pony data to server...'

hook.Add 'KeyPress', 'PPM2.RequireData', ->
    hook.Remove 'KeyPress', 'PPM2.RequireData'
    RunConsoleCommand('ppm2_reload')
    timer.Simple 3, -> RunConsoleCommand('ppm2_require')

PPM_HINT_COLOR_FIRST = Color(255, 255, 255)
PPM_HINT_COLOR_SECOND = Color(0, 0, 0)

hook.Add 'HUDPaint', 'PPM2.EditorStatus', ->
    lply = LocalPlayer()
    lpos = lply\EyePos()
    for ply in *player.GetAll()
        if ply ~= lply
            if ply\GetNWBool('PPM2.InEditor')
                pos = ply\EyePos()
                dist = pos\Distance(lpos)
                if dist < 250
                    pos.z += 10
                    alpha = math.Clamp(1 - dist / 250, 0.1, 1)
                    {:x, :y} = pos\ToScreen()
                    draw.DrawText('In PPM/2 Editor', 'HudHintTextLarge', x + 1, y + 1, PPM_HINT_COLOR_SECOND, TEXT_ALIGN_CENTER)
                    draw.DrawText('In PPM/2 Editor', 'HudHintTextLarge', x, y, PPM_HINT_COLOR_FIRST, TEXT_ALIGN_CENTER)

concommand.Add 'ppm2_cleanup', ->
    for ent in *ents.GetAll()
        if ent.isPonyPropModel and not IsValid(ent.manePlayer)
            ent\Remove()
    PPM2.Message('All unused models were removed')

timer.Create 'PPM2.ModelCleanup', 60, 0, ->
    for ent in *ents.GetAll()
        if ent.isPonyPropModel and not IsValid(ent.manePlayer)
            ent\Remove()


Return an instance of the class LP instead of the class LP

export ^

class lp
	-- Private
	BASELAYER = nil
	DEG = nil
	INT_MAX_VALUE = nil
	NUMBER_MAX_VALUE = nil
	RAD = nil
	VERSION = "0.0.1"

	@_gameTime: nil
	@_renderTime: nil
	@_systemTime: nil
	@_updateTime: nil
	@assignedFrameRate: nil
	@blackColor: nil
	@bounds: nil
	@buffer: nil
	@camera: nil
	@console: nil
	@defaultFont: nil
	@elapsed: nil
	@engine: nil
	@entity: nil
	@fixed: nil
	@focused: nil
	@frameRate: nil
	@fullscreen: nil
	@halfHeight: nil
	@halfWidth: nil
	@height: nil
	@log: nil
	@matrix: nil
	@orientations: nil
	@pan: nil
	@point: nil
	@point2: nil
	@random: nil
	@randomSeed: nil
	@rate: nil
	@rect: nil
	@renderMode: nil
	@scene: nil
	@screen: nil
	@sprite: nil
	@stage: nil
	@tweener: nil
	@volume: nil
	@watch: nil
	@width: nil
	@windowHeight: nil
	@windowWidth: nil
	@world: nil
	@zero: nil

	@alarm: (delay, complete, typeweenType, tweener) ->
	@anchorTo: (object, anchor, distance) ->
	@angle: (x1, y1, x2, y2) ->
	@angleDifference: (angle1, angle2) ->
	@angleXY: (object, angle, length, x, y) ->
	@approach: (value, target, amount) ->
	@choose: (objs) ->
	@clamp: (value, min, max) ->
	@clampInRect: (object, x, y, width, height, padding) ->
	@clear: (array) ->
	@colorLerp: (fromColor, toColor, t) ->
	@consoleEnabled: ->
	@convertColor: (color) ->
	@createBitmap: (width, height, transparent, color) ->
	@distance: (x1, y1, x2, y2) ->
	@distanceRectPoint: (px, py, rx, ry, rw, rh) ->
	@distanceRects: (x1, y1, w1, h1, x2, y2, w2, h2) ->
	@distanceSquared: (x1, y1, x2, y2) ->
	@frames: (from_frame, to_frame, skip) ->
	@getBitmap: (source) ->
	@getBlue: (color) ->
	@getColorHSV: (h, s, v) ->
	@getColorHue: (color) ->
	@getColorRGB: (R, G, B) ->
	@getColorSaturation: (color) ->
	@getColorValue: (color) ->
	@getGreen: (color) ->
	@getRed: (color) ->

	DEG: ->
		DEG

	NUMBER_MAX_VALUE: ->
		NUMBER_MAX_VALUE

	RAD: ->
		RAD

	VERSION: ->
		VERSION

	@gotoIsNull: ->
	@lerp: (a, b, t) ->
	@next: (current, options, loop) ->
	@prev: (current, options, loop) ->

	rand: (amount) ->
		math.random(amount)

	randomizeSeed: ->
		math.randomseed os.time()

	@resetCamera: ->
	@resize: (width, height) ->
	@rotateAround: (object, anchor, angle, relative) ->
	@round: (num, precision) ->
	@scale: (value, min, max, min2, max2) ->
	@scaleClamp: (value, min, max, min2, max2) ->
	@setCamera: (x, y) ->
	@shuffle: (a) ->
	@sign: (value) ->
	@stepTowards: (object, x, y, distance) ->
	@swap: (current, a, b) ->
	@swapScene: ->
	@timeFlag: ->
	@tween: (object, values, duration, options) ->

LP = lp!

export ^

class LP
	-- Private
	BASELAYER = nil
	DEG = nil
	INT_MAX_VALUE = nil
	NUMBER_MAX_VALUE = nil
	RAD = nil
	VERSION = "0.0.1"

	@_gameTime: nil
	@_renderTime: nil
	@_systemTime: nil
	@_updateTime: nil
	@assignedFrameRate: nil
	@blackColor: nil
	@bounds: nil
	@buffer: nil
	@camera: nil
	@console: nil
	@defaultFont: nil
	@elapsed: nil
	@engine: nil
	@entity: nil
	@fixed: nil
	@focused: nil
	@frameRate: nil
	@fullscreen: nil
	@halfHeight: nil
	@halfWidth: nil
	@height: nil
	@log: nil
	@matrix: nil
	@orientations: nil
	@pan: nil
	@point: nil
	@point2: nil
	@random: nil
	@randomSeed: nil
	@rate: nil
	@rect: nil
	@renderMode: nil
	@scene: nil
	@screen: nil
	@sprite: nil
	@stage: nil
	@tweener: nil
	@volume: nil
	@watch: nil
	@width: nil
	@windowHeight: nil
	@windowWidth: nil
	@world: nil
	@zero: nil

	@alarm: (delay, complete, typeweenType, tweener) ->
	@anchorTo: (object, anchor, distance) ->
	@angle: (x1, y1, x2, y2) ->
	@angleDifference: (angle1, angle2) ->
	@angleXY: (object, angle, length, x, y) ->
	@approach: (value, target, amount) ->
	@choose: (objs) ->
	@clamp: (value, min, max) ->
	@clampInRect: (object, x, y, width, height, padding) ->
	@clear: (array) ->
	@colorLerp: (fromColor, toColor, t) ->
	@consoleEnabled: ->
	@convertColor: (color) ->
	@createBitmap: (width, height, transparent, color) ->
	@distance: (x1, y1, x2, y2) ->
	@distanceRectPoint: (px, py, rx, ry, rw, rh) ->
	@distanceRects: (x1, y1, w1, h1, x2, y2, w2, h2) ->
	@distanceSquared: (x1, y1, x2, y2) ->
	@frames: (from_frame, to_frame, skip) ->
	@getBitmap: (source) ->
	@getBlue: (color) ->
	@getColorHSV: (h, s, v) ->
	@getColorHue: (color) ->
	@getColorRGB: (R, G, B) ->
	@getColorSaturation: (color) ->
	@getColorValue: (color) ->
	@getGreen: (color) ->
	@getRed: (color) ->

	@DEG: ->
		DEG

	@NUMBER_MAX_VALUE: ->
		NUMBER_MAX_VALUE

	@RAD: ->
		RAD

	@VERSION: ->
		VERSION

	@gotoIsNull: ->
	@lerp: (a, b, t) ->
	@next: (current, options, loop) ->
	@prev: (current, options, loop) ->

	@rand: (amount) ->
		math.random(amount)

	@randomizeSeed: ->
		math.randomseed os.time()

	@resetCamera: ->
	@resize: (width, height) ->
	@rotateAround: (object, anchor, angle, relative) ->
	@round: (num, precision) ->
	@scale: (value, min, max, min2, max2) ->
	@scaleClamp: (value, min, max, min2, max2) ->
	@setCamera: (x, y) ->
	@shuffle: (a) ->
	@sign: (value) ->
	@stepTowards: (object, x, y, distance) ->
	@swap: (current, a, b) ->
	@swapScene: ->
	@timeFlag: ->
	@tween: (object, values, duration, options) ->

lp = LP!