mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-04 20:57:49 +00:00
204 lines
5.6 KiB
Lua
204 lines
5.6 KiB
Lua
-----------------
|
|
--DEFAULT VALUES-
|
|
-----------------
|
|
loaded = false
|
|
on = false
|
|
|
|
|
|
|
|
|
|
---------------
|
|
--PLUGIN SETUP-
|
|
---------------
|
|
self = PluginManager():CreatePlugin()
|
|
mouse = self:GetMouse()
|
|
mouse.Button1Down:connect(function() onClicked(mouse) end)
|
|
self.Deactivation:connect(function()
|
|
Off()
|
|
end)
|
|
toolbar = self:CreateToolbar("Terrain")
|
|
toolbarbutton = toolbar:CreateButton("", "Tree", "trees.png")
|
|
toolbarbutton.Click:connect(function()
|
|
if on then
|
|
Off()
|
|
elseif loaded then
|
|
On()
|
|
end
|
|
end)
|
|
|
|
|
|
|
|
-----------------------
|
|
--FUNCTION DEFINITIONS-
|
|
-----------------------
|
|
|
|
local Base = Instance.new("Part")
|
|
Base.Name = "Trunk"
|
|
Base.formFactor = "Custom"
|
|
Base.TopSurface = 0
|
|
Base.BottomSurface = 0
|
|
Base.Anchored = false
|
|
Base.BrickColor = BrickColor.new("Reddish brown")
|
|
local Leaves = Base:Clone()
|
|
Leaves.Name = "Leaves"
|
|
Leaves.CanCollide = false
|
|
Leaves.BrickColor = BrickColor.new("Dark green")
|
|
local leafmesh = Instance.new("SpecialMesh")
|
|
leafmesh.MeshType = "FileMesh"
|
|
leafmesh.MeshId = "http://www.watrbx.wtf/asset/?id=1290033"
|
|
leafmesh.TextureId = "http://www.watrbx.wtf/asset/?id=2861779"
|
|
leafmesh.Parent = Leaves
|
|
Instance.new("CylinderMesh",Base)
|
|
|
|
|
|
-- get dot product of yz angles
|
|
function dot(c1,c2)
|
|
local m = CFrame.Angles(math.pi/2,0,0)
|
|
return (c1*m).lookVector:Dot((c2*m).lookVector)
|
|
end
|
|
|
|
-- multiplier for various sizes of foliage
|
|
local leaf_mult = {
|
|
Vector3.new(1.5,1.5,1.2);
|
|
Vector3.new(1.5,1,1.5);
|
|
Vector3.new(1.2,1.5,1.5);
|
|
Vector3.new(1.5,1.5,1.5);
|
|
}
|
|
|
|
function Welder(p0, p1)
|
|
local w = Instance.new("Weld")
|
|
w.Part0 = p0
|
|
w.Part1 = p1
|
|
local CJ = CFrame.new(p0.Position)
|
|
w.C0 = p0.CFrame:inverse() * CJ
|
|
w.C1 = p1.CFrame:inverse() * CJ
|
|
w.Parent = p0
|
|
end
|
|
|
|
function Branch(base,c)
|
|
if c <= 0 then
|
|
-- if the complexity has run out, generate some foliage
|
|
local leaves = Leaves:Clone()
|
|
local vol = base.Size.x+base.Size.y+base.Size.z -- determine size based on branch size
|
|
leaves.Mesh.Scale = leaf_mult[math.random(1,#leaf_mult)]*math.random(vol/3*10,vol/3*12)/10
|
|
leaves.Size = leaves.Mesh.Scale*0.75
|
|
leaves.CFrame = base.CFrame * CFrame.new(0,base.Size.y/2,0) -- center foliage at top of branch
|
|
leaves.Parent = base.Parent
|
|
Welder(leaves, base)
|
|
else
|
|
-- otherwise, make some more branches
|
|
local pos = base.CFrame*CFrame.new(0,base.Size/2,0)
|
|
local height = base.Size.y
|
|
local width = base.Size.x
|
|
local nb = math.random(2,2) -- # of possible branches (2 seems to work fine for now)
|
|
local r = math.random(45,135) -- rotation of branches on y axis
|
|
|
|
-- branch split angle difference
|
|
-- the less complexity, the greater the possible angle
|
|
-- minimum: 20-75; maximum: 40-80
|
|
local da = math.random(20+55/c,40+40/c)
|
|
|
|
-- branch angle (overall angle of all branches)
|
|
local ba = math.random(-da/3,da/3)
|
|
|
|
-- ba+da/2 shouldn't be near or greater than 90 degrees
|
|
|
|
for i=0,nb-1 do -- for each branch
|
|
local branch = base:Clone()
|
|
branch.Name = "Branch"
|
|
local h = height*math.random(95,115)/100 -- height .95 to 1.15 of original
|
|
|
|
-- make new cframe
|
|
-- move new to top of base, then apply branch angle (ba)
|
|
local new = branch.CFrame * CFrame.new(0,height/2,0) * CFrame.Angles(0,0,math.rad(ba))
|
|
-- next, rotate branch so that it faces away from others, also apply overall rotation (r)
|
|
-- also, apply the split angle (da)
|
|
-- finally, move branch upward by half it's size
|
|
new = new * CFrame.Angles(0,i*(math.pi*2/nb)+r,math.rad(da/2)) * CFrame.new(0,h/2,0)
|
|
|
|
-- determine width by branch's final angle; greater the angle, smaller the width
|
|
-- also shave off a bit of width for more dramatic change in size
|
|
-- a frustum cone mesh would really help here
|
|
local w = dot(new,branch.CFrame)*width*0.9
|
|
|
|
branch.Size = Vector3.new(w,h,w)
|
|
branch.CFrame = new
|
|
branch.Parent = base.Parent
|
|
Welder(branch, base)
|
|
|
|
-- create the next set of branches with one less complexity
|
|
Branch(branch,c-1)
|
|
end
|
|
end
|
|
--wait() -- remove to generate faster
|
|
end
|
|
|
|
-- Main Function ----------------
|
|
function GenerateTree(location,complexity,width,height)
|
|
--[[
|
|
location: position tree will "sprout" out of
|
|
complexity: # of times to branch out
|
|
determines overall size and quality of tree
|
|
produces between m^c+(m^(c+1)-1)/(m-1) parts,
|
|
where c is complexity,
|
|
and m is either the min or max # of possible branches
|
|
(currently, both min and max are 2)
|
|
width: initial x/z size of tree base
|
|
determines overall thickness of tree
|
|
height: initial y size of tree base
|
|
contributes to sparseness of tree
|
|
]]
|
|
print("TreeGen - complexity: " .. complexity .. ", width: " .. width .. ", height: " .. height)
|
|
local tree = Instance.new("Model")
|
|
tree.Name = "Tree"
|
|
tree.Parent = workspace
|
|
local base = Base:Clone()
|
|
base.Parent = tree
|
|
base.Size = Vector3.new(width,height,width)
|
|
-- move up by half its height, and rotate randomly
|
|
base.CFrame = CFrame.new(location) * CFrame.new(0,height/2,0) * CFrame.Angles(0,math.rad(math.random(1,360)),0)
|
|
leafmesh.VertexColor = Vector3.new((math.random() * .1) + .9, (math.random() * .4) + .6, 1)
|
|
-- start branching
|
|
Branch(base,complexity)
|
|
return base
|
|
end
|
|
|
|
|
|
function onClicked(mouse)
|
|
if on then
|
|
local targetPart = mouse.Target
|
|
local newTrunk = GenerateTree(mouse.Hit.p, math.random(3,6), math.random(2,4), math.random(5,10))
|
|
|
|
if targetPart and targetPart:IsA("Terrain") then Welder(newTrunk, targetPart) end -- make trees stick to terrain
|
|
end
|
|
end
|
|
|
|
function On()
|
|
self:Activate(true)
|
|
toolbarbutton:SetActive(true)
|
|
on = true
|
|
end
|
|
|
|
function Off()
|
|
toolbarbutton:SetActive(false)
|
|
on = false
|
|
end
|
|
|
|
|
|
|
|
|
|
------
|
|
--GUI-
|
|
------
|
|
|
|
--screengui
|
|
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
|
|
|
|
|
|
|
|
|
|
--------------------------
|
|
--SUCCESSFUL LOAD MESSAGE-
|
|
--------------------------
|
|
loaded = true
|
|
print("Tree Plugin Loaded") |