First stable release!

This commit is contained in:
CloneTrooper1019 2019-11-10 00:39:43 -06:00
parent 65c8c4db72
commit 5fd0da89a9
51 changed files with 2141 additions and 648 deletions

2
.gitignore vendored
View File

@ -1,2 +0,0 @@
SNZ_CORE.rbx*
SNZ_SHARED.rbx*

14
.vscode/tasks.json vendored
View File

@ -5,20 +5,14 @@
[
{
"type": "shell",
"label": "Package Game (Core)",
"command": "rojo build --output SNZ_CORE.rbxmx core.project.json",
"group":
"label": "Upload Game",
"command": "powershell -ExecutionPolicy ByPass -File UploadGame.ps1",
"group":
{
"kind": "build",
"isDefault": true
}
},
{
"type": "shell",
"label": "Package Game (Shared)",
"command": "rojo build --output SNZ_SHARED.rbxmx shared.project.json",
}
]
}

350
Bin/.gitignore vendored Normal file
View File

@ -0,0 +1,350 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{957A7717-A3CB-41B0-A17C-0E638017E915}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BevelConverter</RootNamespace>
<AssemblyName>BevelConverter</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="LZ4">
<HintPath>Packages\LZ4.dll</HintPath>
</Reference>
<Reference Include="RobloxFileFormat, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>Packages\RobloxFileFormat.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Extensions\Formatting.cs" />
<Compile Include="Extensions\RegistryHelper.cs" />
<Compile Include="Geometry\Mesh.cs" />
<Compile Include="Geometry\Vertex.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<EmbeddedResource Include="Resources\Bevels.mesh">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<None Include="Resources\BevelPart.rbxm" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BevelConverter", "BevelConverter\BevelConverter.csproj", "{957A7717-A3CB-41B0-A17C-0E638017E915}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{957A7717-A3CB-41B0-A17C-0E638017E915}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{957A7717-A3CB-41B0-A17C-0E638017E915}.Debug|Any CPU.Build.0 = Debug|Any CPU
{957A7717-A3CB-41B0-A17C-0E638017E915}.Release|Any CPU.ActiveCfg = Release|Any CPU
{957A7717-A3CB-41B0-A17C-0E638017E915}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,94 @@
using System.Globalization;
using System.Linq;
// This global class defines extension methods to numeric types
// where I don't want system globalization to come into play.
public static class Format
{
private const string decimalFmt = "0.00";
private static CultureInfo invariant => CultureInfo.InvariantCulture;
private static string filterNan(string value, string replace = decimalFmt)
{
if (value.ToLower() == "nan")
value = replace;
return value;
}
public static string ToInvariantString(this float value)
{
string result = value.ToString(decimalFmt, invariant);
return filterNan(result);
}
public static string ToInvariantString(this double value)
{
string result = value.ToString(decimalFmt, invariant);
return filterNan(result);
}
public static string ToInvariantString(this int value)
{
return value.ToString(invariant);
}
public static string ToInvariantString(this object value)
{
if (value is float)
{
float f = (float)value;
return f.ToInvariantString();
}
else if (value is double)
{
double d = (double)value;
return d.ToInvariantString();
}
else if (value is int)
{
int i = (int)value;
return i.ToInvariantString();
}
else
{
// Unhandled
return value.ToString();
}
}
public static float ParseFloat(string s)
{
return float.Parse(s, invariant);
}
public static double ParseDouble(string s)
{
return double.Parse(s, invariant);
}
public static int ParseInt(string s)
{
return int.Parse(s, invariant);
}
public static string FormatFloats(params float[] values)
{
string[] results = values
.Select(value => value.ToInvariantString())
.ToArray();
for (int i = 0; i < results.Length; i++)
{
string result = results[i];
while (result.Contains(".") && (result.EndsWith("0") || result.EndsWith(".")))
result = result.Substring(0, result.Length - 1);
results[i] = result;
}
return '[' + string.Join("][", results) + ']';
}
}

View File

@ -0,0 +1,17 @@
using System.IO;
using Microsoft.Win32;
public static class RegistryHelper
{
public static RegistryKey GetSubKey(this RegistryKey key, params string[] path)
{
string constructedPath = Path.Combine(path);
return key.CreateSubKey(constructedPath, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryOptions.None);
}
public static string GetString(this RegistryKey key, string name)
{
var result = key.GetValue(name, "");
return result.ToString();
}
}

View File

@ -0,0 +1,410 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using RobloxFiles.DataTypes;
namespace BevelConverter
{
public class Mesh
{
public int Version;
public int NumVerts = 0;
public List<Vertex> Verts;
public int NumFaces = 0;
public List<int[]> Faces;
public ushort NumLODs = 0;
public List<int> LODs;
private static Vector3 ReadVector3(BinaryReader reader)
{
float x = reader.ReadSingle(),
y = reader.ReadSingle(),
z = reader.ReadSingle();
return new Vector3(x, y, z);
}
private static void CheckDefaultLODs(Mesh mesh)
{
if (mesh.NumLODs == 0)
{
mesh.NumLODs = 2;
mesh.LODs = new List<int> { 0, mesh.NumFaces };
}
}
private static void LoadGeometry_Ascii(StringReader reader, Mesh mesh)
{
string header = reader.ReadLine();
if (!header.StartsWith("version 1"))
throw new Exception("Expected version 1 header, got: " + header);
string version = header.Substring(8);
float vertScale = (version == "1.00" ? 0.5f : 1);
if (int.TryParse(reader.ReadLine(), out mesh.NumFaces))
mesh.NumVerts = mesh.NumFaces * 3;
else
throw new Exception("Expected 2nd line to be the polygon count.");
mesh.Faces = new List<int[]>();
mesh.Verts = new List<Vertex>();
string polyBuffer = reader.ReadLine();
MatchCollection matches = Regex.Matches(polyBuffer, @"\[(.*?)\]");
int face = 0;
int index = 0;
int target = 0;
var vertex = new Vertex();
foreach (Match m in matches)
{
string vectorStr = m.Groups[1].ToString();
float[] coords = vectorStr.Split(',')
.Select(coord => Format.ParseFloat(coord))
.ToArray();
if (target == 0)
vertex.Position = new Vector3(coords) * vertScale;
else if (target == 1)
vertex.Normal = new Vector3(coords);
else if (target == 2)
vertex.UV = new Vector3(coords[0], 1 - coords[1], 0);
target = (target + 1) % 3;
if (target == 0)
{
mesh.Verts.Add(vertex);
vertex = new Vertex();
if (index % 3 == 0)
{
int v = face * 3;
int[] faceDef = new int[3] { v, v + 1, v + 2 };
mesh.Faces.Add(faceDef);
}
}
}
CheckDefaultLODs(mesh);
}
private static void LoadGeometry_Binary(BinaryReader reader, Mesh mesh)
{
byte[] binVersion = reader.ReadBytes(13);
var headerSize = reader.ReadUInt16();
var vertSize = reader.ReadByte();
var faceSize = reader.ReadByte();
if (mesh.Version >= 3)
{
var lodRangeSize = reader.ReadUInt16();
mesh.NumLODs = reader.ReadUInt16();
}
mesh.NumVerts = reader.ReadInt32();
mesh.NumFaces = reader.ReadInt32();
mesh.LODs = new List<int>();
mesh.Faces = new List<int[]>();
mesh.Verts = new List<Vertex>();
for (int i = 0; i < mesh.NumVerts; i++)
{
Vertex vert = new Vertex()
{
Position = ReadVector3(reader),
Normal = ReadVector3(reader),
UV = ReadVector3(reader)
};
if (vertSize > 36)
{
byte r = reader.ReadByte(),
g = reader.ReadByte(),
b = reader.ReadByte(),
a = reader.ReadByte();
int argb = (a << 24 | r << 16 | g << 8 | b);
vert.Color = Color.FromArgb(argb);
vert.HasColor = true;
}
mesh.Verts.Add(vert);
}
for (int i = 0; i < mesh.NumFaces; i++)
{
int[] face = new int[3];
for (int f = 0; f < 3; f++)
face[f] = reader.ReadInt32();
mesh.Faces.Add(face);
}
if (mesh.NumLODs > 0)
{
for (int i = 0; i < mesh.NumLODs; i++)
{
int lod = reader.ReadInt32();
mesh.LODs.Add(lod);
}
}
else
{
CheckDefaultLODs(mesh);
}
}
public void AddLod(Mesh lodMesh)
{
Verts.AddRange(lodMesh.Verts);
Faces.AddRange(lodMesh.Faces
.Select(face => face
.Select(i => i + NumVerts)
.ToArray()
)
);
NumVerts = Verts.Count;
NumFaces = Faces.Count;
LODs.Add(NumFaces);
NumLODs += 1;
}
public void Save(Stream stream)
{
const ushort HeaderSize = 16;
const byte VertSize = 40;
const byte FaceSize = 12;
const ushort LOD_Size = 4;
byte[] VersionHeader = Encoding.ASCII.GetBytes("version 3.00\n");
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(VersionHeader);
writer.Write(HeaderSize);
writer.Write(VertSize);
writer.Write(FaceSize);
writer.Write(LOD_Size);
writer.Write(NumLODs);
writer.Write(NumVerts);
writer.Write(NumFaces);
for (int i = 0; i < NumVerts; i++)
{
Vertex vertex = Verts[i];
Vector3 pos = vertex.Position;
writer.Write(pos.X);
writer.Write(pos.Y);
writer.Write(pos.Z);
Vector3 norm = vertex.Normal;
writer.Write(norm.X);
writer.Write(norm.Y);
writer.Write(norm.Z);
Vector3 uv = vertex.UV;
writer.Write(uv.X);
writer.Write(uv.Y);
writer.Write(uv.Z);
if (vertex.HasColor)
{
Color color = vertex.Color;
writer.Write(color.R);
writer.Write(color.G);
writer.Write(color.B);
writer.Write(color.A);
}
else
{
writer.Write(-1);
}
}
for (int i = 0; i < NumFaces; i++)
{
int[] faces = Faces[i];
for (int f = 0; f < 3; f++)
{
int face = faces[f];
writer.Write(face);
}
}
for (int i = 0; i < NumLODs; i++)
{
int lod = LODs[i];
writer.Write(lod);
}
}
}
public static Mesh FromObjFile(string filePath)
{
string contents = File.ReadAllText(filePath);
Mesh mesh = new Mesh()
{
Version = 3,
Faces = new List<int[]>(),
Verts = new List<Vertex>()
};
var posTable = new List<Vector3>();
var normTable = new List<Vector3>();
var vertexLookup = new Dictionary<string, int>();
using (StringReader reader = new StringReader(contents))
{
string line;
while ((line = reader.ReadLine()) != null)
{
if (line.Length == 0)
continue;
string[] buffer = line.Split(' ');
string cmd = buffer[0];
if (cmd == "v" || cmd == "vn")
{
float x = float.Parse(buffer[1]),
y = float.Parse(buffer[2]),
z = float.Parse(buffer[3]);
Vector3 value = new Vector3(x, y, z);
var target = (cmd == "v" ? posTable : normTable);
target.Add(value);
}
else if (cmd == "f")
{
int[] face = new int[3];
for (int i = 0; i < 3; i++)
{
string faceDef = buffer[i + 1];
string[] indices = faceDef.Split('/');
int posId = int.Parse(indices[0]) - 1;
int normId = int.Parse(indices[2]) - 1;
string key = $"{posId}/{normId}";
if (!vertexLookup.ContainsKey(key))
{
int faceId = mesh.NumVerts++;
vertexLookup.Add(key, faceId);
Vertex vert = new Vertex()
{
Position = posTable[posId],
Normal = normTable[normId],
UV = new Vector3()
};
mesh.Verts.Add(vert);
}
face[i] = vertexLookup[key];
}
mesh.Faces.Add(face);
mesh.NumFaces++;
}
}
}
CheckDefaultLODs(mesh);
return mesh;
}
public static Mesh FromBuffer(byte[] data)
{
string file = Encoding.ASCII.GetString(data);
if (!file.StartsWith("version "))
throw new Exception("Invalid .mesh header!");
string versionStr = file.Substring(8, 4);
double version = Format.ParseDouble(versionStr);
Mesh mesh = new Mesh();
mesh.Version = (int)version;
IDisposable disposeThis;
if (mesh.Version == 1)
{
StringReader buffer = new StringReader(file);
LoadGeometry_Ascii(buffer, mesh);
disposeThis = buffer;
}
else if (mesh.Version == 2 || mesh.Version == 3)
{
MemoryStream stream = new MemoryStream(data);
using (BinaryReader reader = new BinaryReader(stream))
LoadGeometry_Binary(reader, mesh);
disposeThis = stream;
}
else
{
throw new Exception($"Unknown .mesh file version: {version}");
}
disposeThis.Dispose();
disposeThis = null;
return mesh;
}
public static Mesh FromStream(Stream stream)
{
byte[] data;
using (MemoryStream buffer = new MemoryStream())
{
stream.CopyTo(buffer);
data = buffer.ToArray();
}
return FromBuffer(data);
}
public static Mesh FromFile(string path)
{
using (FileStream meshStream = File.OpenRead(path))
{
return FromStream(meshStream);
}
}
}
}

View File

@ -0,0 +1,15 @@
using System.Drawing;
using RobloxFiles.DataTypes;
namespace BevelConverter
{
public class Vertex
{
public Vector3 Position;
public Vector3 Normal;
public Vector3 UV;
public bool HasColor = false;
public Color Color;
}
}

View File

@ -0,0 +1,288 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Forms;
using RobloxFiles;
using RobloxFiles.DataTypes;
using RobloxFiles.XmlFormat;
using Microsoft.Win32;
namespace BevelConverter
{
class Program
{
private const string uploadNewMesh = "https://data.roblox.com/ide/publish/UploadNewMesh";
private static string bevelCacheDir;
private static string studioCookies = "";
private static string xCsrfToken = "Fetch";
private static Random rng = new Random();
static void addNoise(ref float value)
{
float noise = (float)(-1e-6 + (rng.NextDouble() * 2e-6));
value += noise;
}
static Mesh CreateBevelMesh(Vector3 size, bool reupload = false)
{
byte[] baseMesh = Properties.Resources.Bevels;
Mesh bevels = Mesh.FromBuffer(baseMesh);
float sx = (size.X - 1f) / 2f,
sy = (size.Y - 1f) / 2f,
sz = (size.Z - 1f) / 2f;
if (reupload)
{
addNoise(ref sx);
addNoise(ref sy);
addNoise(ref sz);
}
foreach (Vertex vert in bevels.Verts)
{
Vector3 pos = vert.Position;
float x = pos.X;
x += (x >= 0 ? sx : -sx);
float y = pos.Y;
y += (y >= 0 ? sy : -sy);
float z = pos.Z;
z += (z >= 0 ? sz : -sz);
vert.Position = new Vector3(x, y, z);
}
return bevels;
}
static long UploadMesh(Mesh mesh, string name, string desc)
{
string uploadName = WebUtility.UrlEncode(name);
string uploadDesc = WebUtility.UrlEncode(desc);
string address = $"{uploadNewMesh}?name={uploadName}&description={uploadDesc}";
var request = WebRequest.Create(address) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "*/*";
request.UserAgent = "RobloxStudio/WinInet";
request.Headers.Set("Cookie", studioCookies);
request.Headers.Set("X-CSRF-TOKEN", xCsrfToken);
using (Stream writeStream = request.GetRequestStream())
{
mesh.Save(writeStream);
writeStream.Close();
}
HttpWebResponse response = null;
try
{
var result = request.GetResponse();
response = result as HttpWebResponse;
}
catch (WebException e)
{
response = e.Response as HttpWebResponse;
if (response.StatusDescription.Contains("XSRF"))
{
// Update the X-CSRF-TOKEN.
xCsrfToken = response.Headers.Get("X-CSRF-TOKEN");
// Retry the request again.
return UploadMesh(mesh, name, desc);
}
else
{
throw e;
}
}
long assetId = -1;
using (Stream stream = response.GetResponseStream())
{
byte[] data;
using (MemoryStream buffer = new MemoryStream())
{
stream.CopyTo(buffer);
data = buffer.ToArray();
}
string strAssetId = Encoding.ASCII.GetString(data);
assetId = long.Parse(strAssetId);
}
return assetId;
}
static string ProcessInput(string input)
{
float[] xyz;
try
{
var inputData = input.Split('~', ',', ' ')
.Select(str => str.Trim())
.Where(str => str.Length > 0)
.Select(str => Format.ParseFloat(str));
if (inputData.Count() != 3)
throw new Exception();
xyz = inputData.ToArray();
input = Format.FormatFloats(xyz);
}
catch
{
Console.WriteLine("\tInvalid input: {0}", input);
return null;
}
string name = $"Bevel{input}";
const string desc = "[AUTO-GENERATED BEVEL MESH]";
string cached = Path.Combine(bevelCacheDir, $"{name}.txt");
bool exists = File.Exists(cached);
bool moderated = false;
if (exists)
{
string contents = File.ReadAllText(cached);
moderated = (contents.ToLower() == "moderated");
}
if (moderated || !exists)
{
Vector3 size = new Vector3(xyz);
Mesh mesh = CreateBevelMesh(size, moderated);
Console.WriteLine("\tUploading {0}...", name);
long assetId = UploadMesh(mesh, name, desc);
File.WriteAllText(cached, assetId.ToString());
}
string result = "rbxassetid://" + File.ReadAllText(cached);
Console.WriteLine(" Result -> {0} (copied to clipboard)", result);
return result;
}
static void ProcessFileArg(string filePath)
{
RobloxFile file = RobloxFile.Open(filePath);
Instance exportBin = file.FindFirstChild("ExportBin");
if (exportBin != null)
exportBin.Name = "BevelCache";
else
return;
Instance[] unions = exportBin.GetChildren()
.Where((child) => child.ClassName == "UnionOperation")
.OrderBy(child => child.Name)
.ToArray();
for (int i = 0; i < unions.Length; i++)
{
Instance union = unions[i];
string name = union.Name;
Console.WriteLine("Working on {0}... ({1}/{2})", union.Name, i, unions.Length);
union.ClassName = "MeshPart";
union.RemoveProperty("AssetId");
union.RemoveProperty("MeshData");
union.RemoveProperty("ChildData");
union.RemoveProperty("UsePartColor");
string meshId = ProcessInput(name);
if (meshId == null)
continue;
union.SetProperty("MeshId", meshId);
}
using (FileStream export = File.OpenWrite(filePath))
file.Save(export);
if (file is XmlRobloxFile)
Process.Start(filePath);
Console.WriteLine("Finished processing order!");
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
Console.Clear();
}
[STAThread]
static void Main(string[] args)
{
string localAppData = Environment.GetEnvironmentVariable("LocalAppData");
bevelCacheDir = Path.Combine(localAppData, "BevelCache");
if (!Directory.Exists(bevelCacheDir))
Directory.CreateDirectory(bevelCacheDir);
RegistryKey robloxCookies = Registry.CurrentUser.GetSubKey
(
"SOFTWARE", "Roblox",
"RobloxStudioBrowser",
"roblox.com"
);
foreach (string name in robloxCookies.GetValueNames())
{
string cookie = robloxCookies.GetString(name);
int startIndex = cookie.IndexOf("COOK::<") + 7;
int endIndex = cookie.IndexOf('>', startIndex);
cookie = cookie.Substring(startIndex, endIndex - startIndex);
if (studioCookies.Length > 0)
studioCookies += "; ";
studioCookies += $"{name}={cookie}";
}
if (args.Length > 0)
{
string filePath = args[0];
ProcessFileArg(filePath);
}
Console.WriteLine("Enter bevel sizes in format: 'X ~ Y ~ Z' to generate them as .mesh files!");
Console.WriteLine(" (Also accepts format: 'X, Y, Z' and 'X Y Z')");
while (true)
{
Console.Write("> ");
string inputLine = Console.ReadLine();
if (inputLine == "exit")
break;
string assetId = ProcessInput(inputLine);
Clipboard.SetText(assetId);
}
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("BevelConverter")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BevelConverter")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("957a7717-a3cb-41b0-a17c-0e638017e915")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,83 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace BevelConverter.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BevelConverter.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
internal static byte[] BevelPart {
get {
object obj = ResourceManager.GetObject("BevelPart", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
internal static byte[] Bevels {
get {
object obj = ResourceManager.GetObject("Bevels", resourceCulture);
return ((byte[])(obj));
}
}
}
}

View File

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="BevelPart" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\BevelPart.rbxm;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="Bevels" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Bevels.mesh;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
</root>

Binary file not shown.

Binary file not shown.

View File

@ -10,7 +10,8 @@ local PopperCam = {} -- Guarantees your players won't see outside the bounds of
local POP_RESTORE_RATE = 0.3
local MIN_CAMERA_ZOOM = 0.5
local VALID_SUBJECTS = {
local VALID_SUBJECTS =
{
'Humanoid',
'VehicleSeat',
'SkateboardPlatform',

View File

@ -23,14 +23,14 @@ local function onDescendantAdded(exp)
local expObj = Instance.new("SphereHandleAdornment")
expObj.Adornee = expAdorn
expObj.Radius = exp.BlastRadius
expObj.Color3 = Color3.new(1,0,0)
expObj.Color3 = Color3.new(1, 0, 0)
expObj.CFrame = cf
expObj.Parent = expAdorn
lifeTime = 1
if exp.BlastRadius > 1 then
lifeTime = lifeTime - (1/exp.BlastRadius)
lifeTime = lifeTime - (1 / exp.BlastRadius)
end
else
local e = classicExp:Clone()

View File

@ -2,15 +2,21 @@ local RunService = game:GetService("RunService")
local ffAdorns = workspace:WaitForChild("_ForceFieldAdorns")
local registry = {}
local cycleStates = {}
local cycleStates = setmetatable({}, { __mode = 'k'})
local cycles = 60
local function onChildAdded(child)
if child:IsA("SelectionBox") then
spawn(function ()
while not child.Adornee do
if not child:IsDescendantOf(ffAdorns) then
return
end
child.Changed:Wait()
end
registry[child] = child.Adornee
end)
end
@ -24,24 +30,29 @@ end
local function update()
local now = tick()
for adorn,adornee in pairs(registry) do
for adorn, adornee in pairs(registry) do
local model = adornee:FindFirstAncestorWhichIsA("Model")
local key
if model then
local key = model:GetFullName()
local startTime = cycleStates[key]
local startTime = cycleStates[model]
if not startTime then
startTime = tick()
cycleStates[key] = startTime
cycleStates[model] = startTime
end
local cycle = math.floor(((now-startTime)*2) * cycles) % (cycles*2)
local cycle = math.floor(((now - startTime) * 2) * cycles) % (cycles * 2)
if cycle > cycles then
cycle = cycles - (cycle - cycles)
end
local invertCycle = cycles - cycle
adorn.Color3 = Color3.new(cycle/cycles, 0, invertCycle/cycles)
adorn.Color3 = Color3.new(cycle / cycles, 0, invertCycle / cycles)
adorn.Transparency = 0
end
adorn.Visible = adornee:IsDescendantOf(workspace) and adornee.LocalTransparencyModifier < 1
end
end
@ -51,5 +62,6 @@ for _,v in pairs(ffAdorns:GetChildren()) do
end
RunService.Heartbeat:Connect(update)
ffAdorns.ChildAdded:Connect(onChildAdded)
ffAdorns.ChildRemoved:Connect(onChildRemoved)

View File

@ -1,17 +1,14 @@
return function (script)
local RunService = game:GetService("RunService")
local TeleportService = game:GetService("TeleportService")
spawn(function ()
while RunService.RenderStepped:Wait() do
if TeleportService:GetTeleportSetting("FPSCapTo30") then
local t0 = tick()
RunService.Heartbeat:Wait()
debug.profilebegin("30 FPS Cap")
repeat until (t0+0.0325) < tick()
debug.profileend()
end
end
end)
local RunService = game:GetService("RunService")
local TeleportService = game:GetService("TeleportService")
while RunService.RenderStepped:Wait() do
if TeleportService:GetTeleportSetting("FPSCapTo30") then
local t0 = tick()
RunService.Heartbeat:Wait()
debug.profilebegin("30 FPS Cap")
repeat until (t0 + 0.0325) < tick()
debug.profileend()
end
end

View File

@ -1,14 +1,16 @@
local humanoids = {}
local humanoids = setmetatable({}, { __mode = 'k' })
local player = game.Players.LocalPlayer
local pgui = player:WaitForChild("PlayerGui")
local healthBase = script:WaitForChild("Health")
local rs = game:GetService("RunService")
local farStudsOffset = Vector3.new(0,2,0)
local closeStudsOffset = Vector3.new(0,1,0)
local farSize = UDim2.new(0,50,0,20)
local closeSize = UDim2.new(0,100,0,30)
local farSize = UDim2.new(0, 50, 0, 20)
local closeSize = UDim2.new(0, 100, 0, 30)
local function isFinite(num)
return num == num and num ~= -1/0 and num ~= 1/0
@ -100,18 +102,12 @@ local function setupHumanoid(h)
h.AncestryChanged:Connect(onAncestryChanged)
end
local function recurse(obj)
for _,v in pairs(obj:GetChildren()) do
if v:IsA("Humanoid") then
humanoids[v] = true
else
recurse(v)
end
for _,desc in pairs(workspace:GetDescendants()) do
if desc:IsA("Humanoid") then
humanoids[desc] = true
end
end
recurse(workspace)
for h in pairs(humanoids) do
humanoids[h] = true
@ -127,13 +123,8 @@ local function onDescendantAdded(child)
end
end
local function onDescendantRemoved(child)
if humanoids[child] then
humanoids[child] = nil
end
for _,desc in pairs(workspace:GetDescendants()) do
onDescendantAdded(desc)
end
recurse(workspace)
workspace.DescendantAdded:connect(onDescendantAdded)
workspace.DescendantRemoving:connect(onDescendantRemoved)
workspace.DescendantAdded:Connect(onDescendantAdded)

View File

@ -1,185 +0,0 @@
local UserInputService = game:GetService("UserInputService")
local ContextActionService = game:GetService("ContextActionService")
local Debris = game:GetService("Debris")
local gateway = script.Parent
local tool = gateway.Parent
local remote = gateway:WaitForChild("Gateway")
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local isActive = false
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Standard Input
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local function activate(active,cf)
isActive = active
remote:FireServer("SetActive",active,cf)
while isActive do
wait(.1)
remote:FireServer("SetTarget",mouse.Hit)
end
end
local function onKey(input)
local keyCode = input.KeyCode.Name
local down = (input.UserInputState.Name == "Begin")
remote:FireServer("KeyEvent",keyCode,down)
end
local function onInputBegan(input,gameProcessed)
if not gameProcessed then
local name = input.UserInputType.Name
if name == "MouseButton1" then
activate(true,mouse.Hit)
elseif name == "Touch" then
wait(.1)
local state = input.UserInputState.Name
if state == "End" or state == "Cancel" then
activate(true,mouse.Hit)
end
elseif name == "Gamepad1" then
local keyCode = input.KeyCode.Name
if keyCode == "ButtonR2" then
activate(true,mouse.Hit)
end
elseif name == "Keyboard" then
onKey(input)
end
end
end
local function onInputEnded(input,gameProcessed)
if not gameProcessed and isActive then
local name = input.UserInputType.Name
if name == "MouseButton1" or name == "Touch" or name == "Gamepad1" then
activate(false,mouse.Hit)
elseif name == "Keyboard" then
onKey(input)
end
end
end
UserInputService.InputBegan:Connect(onInputBegan)
UserInputService.InputEnded:Connect(onInputEnded)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Special case Input
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local mControlScheme = tool:WaitForChild("ControlScheme",5)
if mControlScheme then
local controlSchemeData = require(mControlScheme)
local controlScheme = controlSchemeData.Buttons
local activateContext = controlSchemeData.ActivateContext
local keyEvent = tool:WaitForChild("KeyEvent")
local callbacks = {}
local hands = { L = "Left", R = "Right" }
local handTypes = {"Bumper","Trigger","Joystick (Press)"}
local schemeDocs =
{
Keyboard = {"Hold Left Mouse Button - " .. activateContext};
Gamepad = {"Hold Right Trigger - " .. activateContext};
}
for key,data in pairs(controlScheme) do
local down = false
callbacks[key] = function (actionName,inputState,inputObject)
if (inputState.Name == "Begin") and not down then
down = true
if data.Client then
keyEvent:Fire(key,true)
else
remote:FireServer("KeyEvent",key,true)
end
elseif (inputState.Name == "End") and down then
down = false
if data.Client then
keyEvent:Fire(key,false)
else
remote:FireServer("KeyEvent",key,false)
end
end
end
local xBtn = data.XboxButton:gsub("Button","")
if #xBtn == 2 then
local handId,hTypeId = xBtn:match("(%u)(%d)")
local hand = hands[handId]
local hType = handTypes[tonumber(hTypeId)]
xBtn = hand .. " " .. hType
else
xBtn = "(" .. xBtn .. ")"
end
table.insert(schemeDocs.Keyboard,key .. " - " .. data.Label)
table.insert(schemeDocs.Gamepad,xBtn .. " - " .. data.Label)
end
local currentSchemeDocMsg
local function onLastInputTypeChanged(inputType)
if currentSchemeDocMsg and not UserInputService.TouchEnabled and not controlSchemeData.HideControls then
local schemeDoc
if inputType.Name:find("Gamepad") then
schemeDoc = "Gamepad"
else
schemeDoc = "Keyboard"
end
currentSchemeDocMsg.Text = schemeDoc .. " Controls:\n\n" .. table.concat(schemeDocs[schemeDoc],"\n")
end
end
local diedCon
local equipped = false
local function onUnequipped()
if equipped then
equipped = false
for key,data in pairs(controlScheme) do
ContextActionService:UnbindAction(data.Label)
end
currentSchemeDocMsg:Destroy()
currentSchemeDocMsg = nil
end
end
local function onEquipped()
if not equipped then
equipped = true
for key,data in pairs(controlScheme) do
ContextActionService:BindAction(data.Label,callbacks[key],true,Enum.KeyCode[data.XboxButton])
ContextActionService:SetTitle(data.Label,data.Label)
end
if UserInputService.TouchEnabled then
spawn(function ()
local playerGui = player:WaitForChild("PlayerGui")
local contextActionGui = playerGui:WaitForChild("ContextActionGui")
local contextButtonFrame = contextActionGui:WaitForChild("ContextButtonFrame")
contextButtonFrame.Size = UDim2.new(3/8,0,3/8,0)
contextButtonFrame.AnchorPoint = Vector2.new(1,1)
contextButtonFrame.Position = UDim2.new(1,0,1,0)
end)
end
currentSchemeDocMsg = Instance.new("Message")
currentSchemeDocMsg.Parent = player
onLastInputTypeChanged(UserInputService:GetLastInputType())
if not diedCon then
local char = tool.Parent
if char then
local humanoid = char:FindFirstChildWhichIsA("Humanoid")
if humanoid then
diedCon = humanoid.Died:Connect(onUnequipped)
end
end
end
end
end
tool.Equipped:Connect(onEquipped)
tool.Unequipped:Connect(onUnequipped)
UserInputService.LastInputTypeChanged:Connect(onLastInputTypeChanged)
end

View File

@ -2,9 +2,9 @@ local RunService = game:GetService("RunService")
local Lighting = game:GetService("Lighting")
local TeleportService = game:GetService("TeleportService")
local c = workspace.CurrentCamera
local camera = workspace.CurrentCamera
local lensFlareNode = camera:FindFirstChild("LensFlareNode")
local lensFlareNode = c:FindFirstChild("LensFlareNode")
if not lensFlareNode then
lensFlareNode = Instance.new("Part")
lensFlareNode.Name = "LensFlareNode"
@ -12,7 +12,7 @@ if not lensFlareNode then
lensFlareNode.Anchored = true
lensFlareNode.CanCollide = false
lensFlareNode.Locked = true
lensFlareNode.Parent = c
lensFlareNode.Parent = camera
end
local lenses =
@ -37,12 +37,11 @@ local function projectRay(ray,length)
return Ray.new(origin,direction.Unit * length)
end
local function computeSunOcclusion()
local sunPos = Lighting:GetSunDirection()
local cf = c.CFrame
local function computeSunOcclusion(sunPos)
local cf = camera.CFrame
if sunPos:Dot(cf.lookVector) > 0 then
local sunView = c:WorldToViewportPoint(cf.p + sunPos)
if sunPos:Dot(cf.LookVector) > 0 then
local sunView = camera:WorldToViewportPoint(cf.Position + sunPos)
local visibility = 0
local total = 0
@ -51,42 +50,48 @@ local function computeSunOcclusion()
local posX = math.floor(sunView.X + dx * 15)
local posY = math.floor(sunView.Y + dy * 15)
local sunRay = c:ViewportPointToRay(posX, posY)
sunRay = projectRay(sunRay,5000)
local sunRay = camera:ViewportPointToRay(posX, posY)
sunRay = projectRay(sunRay, 5000)
local hit, pos = workspace:FindPartOnRay(sunRay, camera)
local hit,pos = workspace:FindPartOnRay(sunRay,c)
if not hit then
visibility = visibility + 1
end
total = total + 1
end
end
visibility = visibility / total
return (1-visibility),sunView
return (1 - visibility), sunView
end
return 0
end
local function asVector2(v3,...)
return Vector2.new(v3.X,v3.Y),...
local function asVector2(v3, ...)
return Vector2.new(v3.X, v3.Y), ...
end
local function update()
if TeleportService:GetTeleportSetting("ClassicSky") then
local vpSize = c.ViewportSize
local vpSize = camera.ViewportSize
local sunDir = Lighting:GetSunDirection()
local sunWP = sunDir * 10e6
local sunSP,inView = asVector2(c:WorldToViewportPoint(sunWP))
local occlusion = inView and computeSunOcclusion() or 1
if occlusion < 1 then
local sunSP, inView = asVector2(camera:WorldToViewportPoint(sunWP))
local occlusion = inView and computeSunOcclusion(sunDir) or 1
if occlusion < 1 and sunDir.Y > -0.1 then
local invSunSP = vpSize - sunSP
local enabled = (inView and occlusion < 1)
local flareBrightness = math.sqrt(math.max(0,sunDir.y*4))
local flareBrightness = math.sqrt(math.max(0, sunDir.Y * 4))
for i,lense in ipairs(lenses) do
for i, lense in ipairs(lenses) do
local radius = lense.Radius / 12
if not lense.Beam then
local a0 = Instance.new("Attachment")
lense.A0 = a0
@ -114,14 +119,15 @@ local function update()
beam.Parent = lensFlareNode
end
local lenseSP = invSunSP:lerp(sunSP,lense.Distance)
local lenseWP = c:ViewportPointToRay(lenseSP.X,lenseSP.Y,1).Origin
local lenseCF = CFrame.new(lenseWP,lenseWP - sunDir)
lense.A0.CFrame = lenseCF * CFrame.new(-radius/2,0,0)
lense.A1.CFrame = lenseCF * CFrame.new(radius/2,0,0)
local lenseSP = invSunSP:Lerp(sunSP, lense.Distance)
local lenseWP = camera:ViewportPointToRay(lenseSP.X, lenseSP.Y, 1).Origin
local lenseCF = CFrame.new(lenseWP, lenseWP - sunDir)
lense.A0.CFrame = lenseCF * CFrame.new(-radius / 2, 0, 0)
lense.A1.CFrame = lenseCF * CFrame.new( radius / 2, 0, 0)
end
lensFlareNode.Parent = c
lensFlareNode.Parent = camera
return
end
end
@ -129,6 +135,4 @@ local function update()
lensFlareNode.Parent = nil
end
return function (script)
RunService:BindToRenderStep("LensFlareUpdate",201,update)
end
RunService:BindToRenderStep("LensFlareUpdate", 201, update)

View File

@ -1,5 +1,6 @@
local TeleportService = game:GetService("TeleportService")
local gameMusic = workspace:WaitForChild("GameMusic",10)
local gameMusic = workspace:WaitForChild("GameMusic", 10)
if gameMusic and TeleportService:GetTeleportSetting("AllowMusic") then
gameMusic:Play()
end

View File

@ -76,7 +76,7 @@
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<int name="LayoutOrder">0</int>
<string name="Name">Frame</string>
<string name="Name">Star</string>
<Ref name="NextSelectionDown">null</Ref>
<Ref name="NextSelectionLeft">null</Ref>
<Ref name="NextSelectionRight">null</Ref>

View File

@ -11,11 +11,11 @@ local UserInputService = game:GetService("UserInputService")
local midnight = 0
local day = 86400
local hour = day/24
local hour = day / 24
local sunRise = day * .25
local sunSet = day * .75
local riseAndSetTime = hour/2
local riseAndSetTime = hour / 2
local times =
{
@ -63,7 +63,7 @@ end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local function r()
return -1 + (math.random()*2)
return -1 + (math.random() * 2)
end
local lastTime = 0
@ -75,11 +75,32 @@ local nightFrame = night:WaitForChild("NightFrame")
local star = script:WaitForChild("Star")
local shadowsOn = true
local black = Color3.new()
for i = 1, 500 do
local toneMap do
toneMap = Instance.new("ColorCorrectionEffect")
toneMap.TintColor = Color3.new(1.25, 1.25, 1.25)
toneMap.Name = "LegacyToneMap"
toneMap.Brightness = 0.03
toneMap.Saturation = 0.07
toneMap.Contrast = -0.15
toneMap.Parent = Lighting
if Lighting.Ambient ~= black then
Lighting.OutdoorAmbient = Lighting.Ambient
Lighting.Ambient = black:Lerp(Lighting.Ambient, 0.5)
end
Lighting.GlobalShadows = true
Lighting.ShadowSoftness = 0.1
end
for i = 1, 3000 do
local bb = star:Clone()
local size = math.random(2, 6) / 2
bb.StudsOffsetWorldSpace = Vector3.new(r(), r(), r()).Unit * 2500
bb.Size = UDim2.new(0, math.random(2, 5), 0, math.random(2, 5))
bb.Star.Transparency = (math.random(1, 4) - 1) / 4
-- bb.Size = UDim2.new(0, size, 0, size)
bb.Adornee = skyAdorn
bb.Parent = skyAdorn
end
@ -104,8 +125,15 @@ local function updateSky()
Lighting.Ambient = Lighting.OutdoorAmbient
end
end
local sunDir = Lighting:GetSunDirection()
local globalLight = math.clamp((sunDir.Y + .033) * 10, 0, 1)
toneMap.Contrast = -0.15 * globalLight
toneMap.Saturation = 0.07 * globalLight
if TeleportService:GetTeleportSetting("ClassicSky") then
local camera = workspace.CurrentCamera
local seconds = Lighting:GetMinutesAfterMidnight() * 60
if seconds < 0 then
@ -115,14 +143,14 @@ local function updateSky()
if seconds ~= lastTime then
local sunDir = game.Lighting:GetSunDirection()
local skyColor = linearSpline(seconds, times, colors)
nightFrame.BackgroundTransparency = globalLight
nightFrame.BackgroundColor3 = skyColor
nightFrame.BackgroundTransparency = math.clamp((sunDir.Y + .033) * 10, 0, 1)
lastTime = seconds
end
local sunDir = Lighting:GetSunDirection()
skyAdorn.CFrame = CFrame.new(c.CFrame.p) * CFrame.new(Vector3.new(), sunDir)
skyAdorn.Parent = (nightFrame.BackgroundTransparency < 1 and c or nil)
skyAdorn.CFrame = CFrame.new(camera.CFrame.Position) * CFrame.new(Vector3.new(), sunDir)
skyAdorn.Parent = (nightFrame.BackgroundTransparency < 1 and camera or nil)
else
skyAdorn.Parent = nil
end

View File

@ -52,6 +52,7 @@ end
local function update()
if TeleportService:GetTeleportSetting("ClassicSky") then
local sunPos = Lighting:GetSunDirection()
if sunPos.Y >= -.1 then
local visibility, sunView = computeSunVisibility()

View File

@ -13,36 +13,38 @@ local isActive = false
-- Standard Input
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local function activate(active,cf)
local function activate(active, cf)
isActive = active
remote:FireServer("SetActive",active,cf)
remote:FireServer("SetActive", active, cf)
while isActive do
wait(.1)
remote:FireServer("SetTarget",mouse.Hit)
remote:FireServer("SetTarget", mouse.Hit)
end
end
local function onKey(input)
local keyCode = input.KeyCode.Name
local down = (input.UserInputState.Name == "Begin")
remote:FireServer("KeyEvent",keyCode,down)
remote:FireServer("KeyEvent", keyCode, down)
end
local function onInputBegan(input,gameProcessed)
if not gameProcessed then
local name = input.UserInputType.Name
if name == "MouseButton1" then
activate(true,mouse.Hit)
activate(true, mouse.Hit)
elseif name == "Touch" then
wait(.1)
local state = input.UserInputState.Name
if state == "End" or state == "Cancel" then
activate(true,mouse.Hit)
activate(true, mouse.Hit)
end
elseif name == "Gamepad1" then
local keyCode = input.KeyCode.Name
if keyCode == "ButtonR2" then
activate(true,mouse.Hit)
activate(true, mouse.Hit)
end
elseif name == "Keyboard" then
onKey(input)
@ -88,25 +90,25 @@ if mControlScheme then
for key,data in pairs(controlScheme) do
local down = false
callbacks[key] = function (actionName,inputState,inputObject)
callbacks[key] = function (actionName, inputState, inputObject)
if (inputState.Name == "Begin") and not down then
down = true
if data.Client then
keyEvent:Fire(key,true)
keyEvent:Fire(key, true)
else
remote:FireServer("KeyEvent",key,true)
remote:FireServer("KeyEvent", key, true)
end
elseif (inputState.Name == "End") and down then
down = false
if data.Client then
keyEvent:Fire(key,false)
else
remote:FireServer("KeyEvent",key,false)
remote:FireServer("KeyEvent", key, false)
end
end
end
local xBtn = data.XboxButton:gsub("Button","")
local xBtn = data.XboxButton:gsub("Button", "")
if #xBtn == 2 then
local handId,hTypeId = xBtn:match("(%u)(%d)")
local hand = hands[handId]
@ -115,8 +117,9 @@ if mControlScheme then
else
xBtn = "(" .. xBtn .. ")"
end
table.insert(schemeDocs.Keyboard,key .. " - " .. data.Label)
table.insert(schemeDocs.Gamepad,xBtn .. " - " .. data.Label)
table.insert(schemeDocs.Keyboard, key .. " - " .. data.Label)
table.insert(schemeDocs.Gamepad, xBtn .. " - " .. data.Label)
end
local currentSchemeDocMsg
@ -150,10 +153,12 @@ if mControlScheme then
local function onEquipped()
if not equipped then
equipped = true
for key,data in pairs(controlScheme) do
ContextActionService:BindAction(data.Label,callbacks[key],true,Enum.KeyCode[data.XboxButton])
ContextActionService:SetTitle(data.Label,data.Label)
end
if UserInputService.TouchEnabled then
spawn(function ()
local playerGui = player:WaitForChild("PlayerGui")
@ -164,9 +169,12 @@ if mControlScheme then
contextButtonFrame.Position = UDim2.new(1,0,1,0)
end)
end
currentSchemeDocMsg = Instance.new("Message")
currentSchemeDocMsg.Parent = player
onLastInputTypeChanged(UserInputService:GetLastInputType())
if not diedCon then
local char = tool.Parent
if char then
@ -181,5 +189,6 @@ if mControlScheme then
tool.Equipped:Connect(onEquipped)
tool.Unequipped:Connect(onUnequipped)
UserInputService.LastInputTypeChanged:Connect(onLastInputTypeChanged)
end

View File

@ -20,9 +20,9 @@ local function onGatewayReceive(sendingPlayer, request, ...)
if request == "SetActive" then
local down, target = ...
assert(typeof(target) == "CFrame","Expected CFrame")
assert(typeof(target) == "CFrame", "Expected CFrame")
humanoid.TargetPoint = target.p
humanoid.TargetPoint = target.Position
if humanoid.Health > 0 and tool:IsDescendantOf(char) then
if down then
@ -33,12 +33,14 @@ local function onGatewayReceive(sendingPlayer, request, ...)
end
elseif request == "SetTarget" then
local target = ...
assert(typeof(target) == "CFrame","Expected CFrame")
humanoid.TargetPoint = target.p
assert(typeof(target) == "CFrame", "Expected CFrame")
humanoid.TargetPoint = target.Position
elseif request == "KeyEvent" then
local key, down = ...
assert(typeof(key) == "string","bad key cast")
assert(typeof(down) == "boolean","bad down state cast")
assert(typeof(key) == "string", "Expected string")
assert(typeof(down) == "boolean", "Expected boolean")
keyEvent:Fire(key, down)
end
end

View File

@ -1,25 +0,0 @@
local CollectionService = game:GetService("CollectionService")
local Lighting = game:GetService("Lighting")
if not CollectionService:HasTag(Lighting, "ConfigApplied") then
local toneMap = Instance.new("ColorCorrectionEffect")
toneMap.TintColor = Color3.new(1.25, 1.25, 1.25)
toneMap.Brightness = 0.03
toneMap.Saturation = 0.07
toneMap.Contrast = -0.15
toneMap.Name = "LegacyToneMap"
toneMap.Parent = Lighting
local black = Color3.new()
if Lighting.Ambient ~= black then
Lighting.OutdoorAmbient = Lighting.Ambient
Lighting.Ambient = black:Lerp(Lighting.Ambient, 0.5)
end
Lighting.GlobalShadows = true
Lighting.ShadowSoftness = 0
CollectionService:AddTag(Lighting, "ConfigApplied")
end

View File

@ -2,7 +2,7 @@ local ServerStorage = game:GetService("ServerStorage")
local StarterPack = game:GetService("StarterPack")
local Players = game:GetService("Players")
local tools = ServerStorage:WaitForChild("Tools")
local tools = ServerStorage:WaitForChild("StandardTools")
local loadTools = ServerStorage:FindFirstChild("LoadTools")
if loadTools then

View File

@ -4,7 +4,7 @@ local loadTime = ServerStorage:FindFirstChild("LoadTime")
if loadTime and loadTime.Value then
while wait() do
Lighting:SetMinutesAfterMidnight((tick()*5)%1440)
Lighting:SetMinutesAfterMidnight((tick() * 5) % 1440)
end
end

View File

@ -29,31 +29,35 @@ local creators =
["ROBLOX Halloween Paintball 2009"] = "Stealth Pilot";
}
local placeData = {}
local function iterPageItems(pages)
return coroutine.wrap(function ()
local pageNum = 1
while true do
for _, item in ipairs(pages:GetCurrentPage()) do
coroutine.yield(item, pageNum)
end
if pages.IsFinished then
break
end
pages:AdvanceToNextPageAsync()
pageNum = pageNum + 1
end
end)
end
local placeData = {}
for place in iterPageItems(places) do
if place.PlaceId ~= game.PlaceId then
if place.Name:lower():find("devtest") then
place.DevTest = true
end
place.Creator = creators[place.Name] or "ROBLOX"
table.insert(placeData,place)
table.insert(placeData, place)
end
end

View File

@ -11,25 +11,25 @@ if GuiService:IsTenFootInterface() then
local ui = script.Parent
local rootFrame = ui:WaitForChild("RootFrame")
local zoomControls = gui:WaitForChild("ZoomControls")
local zoomControls = ui:WaitForChild("ZoomControls")
zoomControls.Visible = false
local backpack = gui:WaitForChild("Backpack")
local backpack = ui:WaitForChild("Backpack")
backpack.Position = UDim2.new(0, 0, 1, 0)
local chat = gui:WaitForChild("Chat")
local chat = ui:WaitForChild("Chat")
chat.Visible = false
local chatPadding = gui:WaitForChild("ChatPadding", 1)
local chatPadding = ui:WaitForChild("ChatPadding", 1)
if chatPadding then
chatPadding:Destroy()
end
local safeChat = gui:WaitForChild("SafeChat")
local safeChat = ui:WaitForChild("SafeChat")
safeChat.Visible = false
local health = gui:WaitForChild("Health")
local health = ui:WaitForChild("Health")
addUIScale(health, 1.5)
end

View File

@ -9,9 +9,9 @@
<BinaryString name="AttributesSerialize"></BinaryString>
<bool name="AutoLocalize">true</bool>
<Color3 name="BackgroundColor3">
<R>0.4980392</R>
<G>0.4980392</G>
<B>0.4980392</B>
<R>0.6</R>
<G>0.6</G>
<B>0.6</B>
</Color3>
<float name="BackgroundTransparency">0.5</float>
<Color3 name="BorderColor3">

View File

@ -9,9 +9,9 @@
<BinaryString name="AttributesSerialize"></BinaryString>
<bool name="AutoLocalize">true</bool>
<Color3 name="BackgroundColor3">
<R>0.5882353</R>
<G>0.5882353</G>
<B>0.5882353</B>
<R>0.6</R>
<G>0.6</G>
<B>0.6</B>
</Color3>
<float name="BackgroundTransparency">0.5</float>
<Color3 name="BorderColor3">
@ -33,9 +33,9 @@
<Ref name="NextSelectionUp">null</Ref>
<UDim2 name="Position">
<XS>0</XS>
<XO>32</XO>
<XO>30</XO>
<YS>0</YS>
<YO>5</YO>
<YO>40</YO>
</UDim2>
<Ref name="RootLocalizationTable">null</Ref>
<float name="Rotation">0</float>

View File

@ -90,7 +90,7 @@ local function rotateCameraTowardsGoal()
local rotation = math.min(0.01, abs)
local cfLocal = focus:toObjectSpace(cf)
camera.CFrame = focus * CFrame.Angles(0, -rotation * ign, 0) * cfLocal
camera.CFrame = focus * CFrame.Angles(0, -rotation * sign, 0) * cfLocal
end
end
end
@ -127,13 +127,15 @@ mouse.TargetFilter = workspace.CurrentCamera
local lastTarget
local lastTargetCanClick = false
local adorn = Instance.new("Part", script)
local disk = Instance.new("CylinderHandleAdornment")
disk.Name = "Disk"
disk.Color3 = Color3.new(0,1,0)
disk.Radius = 1
disk.Height = 0.2
disk.Visible = false
disk.Adornee = workspace.Terrain
disk.Adornee = adorn
disk.Parent = script
local goalDisk = disk:Clone()
@ -220,7 +222,7 @@ local function render3dAdorn()
disk.Visible = canRenderDisk(true)
if disk.Visible then
disk.CFrame = CFrame.new(mouse.Hit.p) * DISK_OFFSET
disk.CFrame = CFrame.new(mouse.Hit.Position) * DISK_OFFSET
mouseIcon.Image = ICON_HOVER
elseif canClickTarget() then
mouseIcon.Image = ICON_CLICK
@ -243,8 +245,9 @@ RunService.Heartbeat:Connect(render3dAdorn)
-- Click Action
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local function onInputBegan(input,gameProcessed)
local goal = mouse.Hit.p
local function onInputBegan(input, gameProcessed)
local goal = mouse.Hit.Position
if not gameProcessed and canRenderDisk() and humanoid then
local name = input.UserInputType.Name

View File

@ -0,0 +1,9 @@
{
"ClassName": "UIAspectRatioConstraint",
"Properties":
{
"AspectRatio": 1.33333,
"DominantAxis": "Height"
}
}

View File

@ -0,0 +1,44 @@
{
"ClassName": "ImageButton",
"Properties":
{
"AnchorPoint": [0, 1],
"BackgroundTransparency": 1,
"Position": [0.0202, 0, 0.7777, 0],
"Size": [0, 32, 0, 32],
"Image": "rbxassetid://991182833"
},
"Children":
[
{
"Name": "Click",
"ClassName": "Sound",
"Properties":
{
"SoundId": "rbxasset://sounds/switch.mp3"
}
},
{
"Name": "Hint",
"ClassName": "ImageLabel",
"Properties":
{
"AnchorPoint": [0.5, 0.75],
"BackgroundTransparency": 1,
"Position": [1, 5, 0, 0],
"Size": [0.75, 0, 0.75, 0],
"Image": "rbxasset://textures/ui/Settings/Help/XButtonDark@2x.png",
"Visible": false
}
}
]
}

View File

@ -1,8 +0,0 @@
{
"ClassName": "Sound",
"Properties":
{
"SoundId": "rbxasset://sounds/switch.mp3"
}
}

View File

@ -1,15 +0,0 @@
{
"ClassName": "ImageLabel",
"Properties":
{
"AnchorPoint": [0.5, 0.75],
"BackgroundTransparency": 1,
"Position": [1, 5, 0, 0],
"Size": [0.75, 0, 0.75, 0],
"Image": "rbxasset://textures/ui/Settings/Help/XButtonDark@2x.png",
"Visible": false
}
}

View File

@ -2,11 +2,14 @@ local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GuiService = game:GetService("GuiService")
local c = workspace.CurrentCamera
local resUpdate = c:GetPropertyChangedSignal("ViewportSize")
local camera = workspace.CurrentCamera
local resUpdate = camera:GetPropertyChangedSignal("ViewportSize")
local safeChat = script.Parent
local click = safeChat:WaitForChild("Click")
local chatButton = safeChat:WaitForChild("ChatButton")
local click = chatButton:WaitForChild("Click")
local gamepadHint = chatButton:WaitForChild("Hint")
local IMG_CHAT = "rbxassetid://991182833"
local IMG_CHAT_DN = "rbxassetid://991182832"
@ -18,21 +21,6 @@ local IMG_CHAT_OVR = "rbxassetid://991182834"
local mSafeChatTree = ReplicatedStorage:WaitForChild("SafeChat")
local safeChatTree = require(mSafeChatTree)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Button Positioning
local IS_PHONE = c.ViewportSize.Y < 600
local function onResolutionUpdate()
local viewPort = c.ViewportSize
local chatX = math.min(25,viewPort.Y/40)
local chatY = (viewPort.X/viewPort.Y) * (viewPort.Y * 0.225)
safeChat.Position = UDim2.new(0,chatX,1,-chatY)
end
onResolutionUpdate()
resUpdate:Connect(onResolutionUpdate)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Safe Chat Tree
@ -59,22 +47,23 @@ end
local function deactivateRootTree()
isActivated = false
safeChat.Image = IMG_CHAT
chatButton.Image = IMG_CHAT
recursivelyDeactivateTree(rootTree)
if GuiService.SelectedObject then
GuiService.SelectedObject = nil
GuiService:RemoveSelectionGroup("SafechatNav")
GuiService:RemoveSelectionGroup("SafeChatNav")
end
end
local function activateRootTree()
isActivated = true
rootTree.Visible = true
safeChat.Image = IMG_CHAT_DN
chatButton.Image = IMG_CHAT_DN
if UserInputService:GetLastInputType() == Enum.UserInputType.Gamepad1 then
GuiService:AddSelectionParent("SafechatNav", safeChat)
GuiService:AddSelectionParent("SafeChatNav", safeChat)
GuiService.SelectedObject = safeChat
end
end
@ -86,8 +75,8 @@ local function assembleTree(tree)
local currentBranch
for i, branch in ipairs(tree.Branches) do
local label = branch.Label
local branches = branch.Branches
local label = branch.Label
local button = tempButton:Clone()
button.Name = label
@ -105,7 +94,7 @@ local function assembleTree(tree)
end
currentBranch = button
button.BackgroundColor3 = Color3.new(0.7,0.7,0.7)
button.BackgroundColor3 = Color3.new(0.7, 0.7, 0.7)
branchFrame.Visible = true
end
@ -118,7 +107,7 @@ local function assembleTree(tree)
submit = false
end
end
if submit then
click:Play()
deactivateRootTree()
@ -137,12 +126,6 @@ end
rootTree = assembleTree(safeChatTree)
rootTree.Parent = safeChat
if IS_PHONE then
local uiScale = Instance.new("UIScale")
uiScale.Parent = rootTree
uiScale.Scale = 0.7
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Button State
@ -152,20 +135,21 @@ local isHovering = false
do
local function onMouseEnter()
if not isActivated then
safeChat.Image = IMG_CHAT_OVR
chatButton.Image = IMG_CHAT_OVR
end
isHovering = true
end
local function onMouseLeave()
if not isActivated then
safeChat.Image = IMG_CHAT
chatButton.Image = IMG_CHAT
end
isHovering = false
end
local function onMouseDown()
safeChat.Image = IMG_CHAT_DN
chatButton.Image = IMG_CHAT_DN
end
local function onMouseUp()
@ -180,11 +164,11 @@ do
end
end
safeChat.MouseEnter:Connect(onMouseEnter)
safeChat.MouseLeave:Connect(onMouseLeave)
chatButton.MouseEnter:Connect(onMouseEnter)
chatButton.MouseLeave:Connect(onMouseLeave)
safeChat.MouseButton1Up:Connect(onMouseUp)
safeChat.MouseButton1Down:Connect(onMouseDown)
chatButton.MouseButton1Up:Connect(onMouseUp)
chatButton.MouseButton1Down:Connect(onMouseDown)
UserInputService.InputBegan:Connect(onInputBegan)
end
@ -193,8 +177,6 @@ end
-- Gamepad Stuff
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local gamepadHint = safeChat:WaitForChild("Hint")
if GuiService:IsTenFootInterface() then
gamepadHint.Visible = true
else

View File

@ -1,14 +1,11 @@
{
"className": "ImageButton",
"className": "Frame",
"properties":
{
"Size": [1, 0, 1, 0],
"AnchorPoint": [0, 1],
"BackgroundTransparency": 1,
"Position": [0, 22, 0.75, 0],
"Size": [0, 32, 0, 30],
"Image": "rbxassetid://991182833"
"Position": [0, 0, 1, 0],
"BackgroundTransparency": 1
}
}

56
UI/Topbar/Config.lua Normal file
View File

@ -0,0 +1,56 @@
return
{
Style =
{
Font = "Cartoon";
AutoButtonColor = false;
BorderSizePixel = 0;
Size = UDim2.new(1, 0, 1, 0);
BackgroundColor3 = Color3.fromRGB(177, 177, 177);
BackgroundTransparency = 0.5;
TextSize = 14;
TextXAlignment = "Left";
TextTransparency = 0.3;
TextStrokeTransparency = 0.9;
};
TextColors =
{
Active = Color3.fromRGB( 77, 77, 77);
Inactive = Color3.fromRGB(156, 156, 156);
};
Verbs =
{
{
Name = "Tools";
Enabled = false;
};
{
Name = "Insert";
Enabled = false;
};
{
Name = "Fullscreen";
Enabled = true;
};
{
Name = "Help";
Label = "Help...";
Enabled = true;
};
{
Name = "Exit";
Label = " Exit";
Enabled = true;
}
}
}

View File

@ -1,74 +1,45 @@
-------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Setup
-------------------------------------------------------------------------------------------------------------------------------------------------------------
local Players = game:GetService("Players")
local GuiService = game:GetService("GuiService")
local RunService = game:GetService("RunService")
local TeleportService = game:GetService("TeleportService")
local UserInputService = game:GetService("UserInputService")
local UserGameSettings = UserSettings():GetService("UserGameSettings")
local topbar = script.Parent
local buttons =
{
Tools =
{
Label = "Tools";
Enabled = false;
Order = 1;
};
local ui = topbar.Parent
local config = require(topbar:WaitForChild("Config"))
Insert =
{
Label = "Insert";
Enabled = false;
Order = 2;
};
local style = config.Style
local verbs = config.Verbs
local textColors = config.TextColors
Fullscreen =
{
Label = "Fullscreen";
Enabled = true;
Order = 3;
};
local buttons = {}
Help =
{
Label = "Help...";
Enabled = true;
Order = 4;
};
for i, verb in ipairs(verbs) do
local name = verb.Name
local enabled = verb.Enabled
local label = verb.Label or name
Exit =
{
Label = " Exit";
Enabled = true;
Order = 5;
}
}
local BTN_COLOR = Color3.fromRGB(177, 177, 177)
local TEXT_ACTIVE = Color3.fromRGB(77, 77, 77)
local TEXT_INACTIVE = Color3.fromRGB(156, 156, 156)
for name, data in pairs(buttons) do
local button = Instance.new("TextButton")
button.Name = name
button.Active = data.Enabled
button.LayoutOrder = data.Order
button.Text = " " .. data.Label
button.LayoutOrder = i
button.Active = enabled
button.Text = " " .. label
button.Font = "Cartoon"
button.AutoButtonColor = false
for key, value in pairs(config.Style) do
button[key] = value
end
button.BorderSizePixel = 0
button.Size = UDim2.new(1, 0, 1, 0)
button.BackgroundColor3 = BTN_COLOR;
button.BackgroundTransparency = 0.5;
button.TextSize = 14
button.TextXAlignment = "Left"
button.TextTransparency = 0.3;
button.TextStrokeTransparency = 0.9;
local textColor = (data.Enabled and TEXT_ACTIVE or TEXT_INACTIVE)
local textColor = (enabled and textColors.Active or textColors.Inactive)
button.TextStrokeColor3 = textColor
button.TextColor3 = textColor
if data.Enabled then
if enabled then
local function onMouseEnter()
button.BackgroundTransparency = 0
end
@ -81,5 +52,135 @@ for name, data in pairs(buttons) do
button.MouseLeave:Connect(onMouseLeave)
end
buttons[name] = button
button.Parent = topbar
end
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Help Button
-------------------------------------------------------------------------------------------------------------------------------------------------------------
local helpButton = buttons.Help
local helpWindow = ui:WaitForChild("HelpWindow")
local helpClose = helpWindow:WaitForChild("Close")
local function onHelpActivated()
helpWindow.Visible = true
end
local function onHelpClosed()
helpWindow.Visible = false
end
helpClose.Activated:Connect(onHelpClosed)
helpButton.Activated:Connect(onHelpActivated)
-------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Fullscreen Button
-------------------------------------------------------------------------------------------------------------------------------------------------------------
local player = Players.LocalPlayer
local fullscreen = buttons.Fullscreen
local function onFullscreenActivated()
if not player:FindFirstChild("FullcreenMsg") then
local msg = Instance.new("Message")
msg.Name = "FullscreenMsg"
msg.Text = "This button is just here for legacy aesthetics, and has no functionality."
if UserInputService.KeyboardEnabled then
msg.Text = msg.Text .. "\nPress F11 to toggle fullscreen!"
end
msg.Parent = player
wait(3)
msg:Destroy()
end
end
local function updateFullscreen()
local text = fullscreen.Text
if UserGameSettings:InFullScreen() then
fullscreen.Text = text:gsub("Full", "x Full")
else
fullscreen.Text = text:gsub("x ", "")
end
end
updateFullscreen()
fullscreen.Activated:Connect(onFullscreenActivated)
UserGameSettings.FullscreenChanged:Connect(updateFullscreen)
-------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Exit Button
-------------------------------------------------------------------------------------------------------------------------------------------------------------
local exitButton = buttons.Exit
local gameJoin = ui:WaitForChild("GameJoin")
local message = gameJoin:WaitForChild("Message")
local exitOverride = gameJoin:WaitForChild("ExitOverride")
local exitBuffer = "Continue holding down 'Back' to return to the menu.\nExiting in...\n%.1f"
local function onExitActivated()
if not exitOverride.Visible then
exitOverride.Visible = true
message.Visible = false
gameJoin.Visible = true
TeleportService:Teleport(998374377)
end
end
local function processExitInput(input, gameProcessed)
if gameProcessed then
return
end
if input.KeyCode == Enum.KeyCode.ButtonSelect then
if exitOverride.Visible then
return
end
if gameJoin.Visible then
return
end
if not game:IsLoaded() then
return
end
local success = true
gameJoin.Visible = true
message.Size = exitOverride.Size
for i = 3, 0, -.1 do
if input.UserInputState ~= Enum.UserInputState.Begin then
success = false
break
end
message.Text = exitBuffer:format(i)
wait(.1)
end
if success then
onExitActivated()
else
gameJoin.Visible = false
end
end
end
if not GuiService:IsTenFootInterface() then
exitButton.Activated:Connect(onExitActivated)
end
UserInputService.InputBegan:Connect(processExitInput)
-------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -4,7 +4,7 @@
"properties":
{
"BackgroundTransparency": 1,
"Position": [0, 80, 0, 0],
"Position": [0, 50, 0, 0],
"Size": [0, 100, 0, 20]
}
}

18
UploadGame.ps1 Normal file
View File

@ -0,0 +1,18 @@
$confirmation = Read-Host "Are you sure you want to update Super Nostalgia Zone? (y/n)"
if ($confirmation -eq 'y')
{
echo "Grabbing cookie..."
$regKey = "HKCU:\Software\Roblox\RobloxStudioBrowser\roblox.com"
$regVal = Get-ItemPropertyValue -Path $regKey -Name ".ROBLOSECURITY"
$cookie = [regex]::Match($regVal, "COOK::<([^>]*)>") | % { $_.Groups[1].Value }
echo "Uploading core..."
rojo upload --asset_id 1011800466 --cookie $cookie core.project.json
echo "Uploading shared..."
rojo upload --asset_id 1027421176 --cookie $cookie shared.project.json
echo Finished!
}

View File

@ -1,54 +1,58 @@
{
"name": "MainModule",
"name": "SNZ_CORE",
"tree":
{
"$path": "core.lua",
"ReplicatedFirst":
"$className": "Folder",
"MainModule":
{
"$className": "Folder",
"JoinScript":
"$path": "core.lua",
"ReplicatedFirst":
{
"$path": "join.client.lua",
"UI":
"$className": "Folder",
"JoinScript":
{
"$path": "UI"
"$path": "join.client.lua",
"UI":
{
"$path": "UI"
}
}
}
},
"ReplicatedStorage":
{
"$path": "Shared"
},
"ServerStorage":
{
"$path": "Server/Resources",
},
"Tools":
"ReplicatedStorage":
{
"$path": "Tools"
"$path": "Shared"
},
"ServerStorage":
{
"$path": "Server/Resources",
"StandardTools":
{
"$path": "Tools"
}
},
"ServerScriptService":
{
"$path": "Server/Scripts"
},
"StarterCharacterScripts":
{
"$path": "Player"
},
"StarterPlayerScripts":
{
"$path": "Client"
}
},
"ServerScriptService":
{
"$path": "Server/Scripts"
},
"StarterCharacterScripts":
{
"$path": "Player"
},
"StarterPlayerScripts":
{
"$path": "Client"
}
}
}

View File

@ -31,7 +31,7 @@
"$className": "ServerStorage",
"$path": "Server/Resources",
"Tools":
"StandardTools":
{
"$path": "Tools"
}
@ -41,7 +41,7 @@
{
"$className": "StarterGui",
"UI [PREVIEW, DO NOT EDIT]":
"UI [PREVIEW]":
{
"$path": "UI",

View File

@ -1,4 +1,5 @@
local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local TeleportService = game:GetService("TeleportService")
@ -9,7 +10,7 @@ local StarterGui = game:GetService("StarterGui")
spawn(function ()
local function setCoreSafe(method, ...)
while not pcall(StarterGui.SetCore, StarterGui, method, ...) do
wait()
RunService.Heartbeat:Wait()
end
end
@ -39,17 +40,10 @@ if playerGui:FindFirstChild("ConnectingGui") then
playerGui.ConnectingGui:Destroy()
end
local IS_PHONE = ui.AbsoluteSize.Y < 600
local topbar = ui:WaitForChild("Topbar")
local gameJoin = ui:WaitForChild("GameJoin")
if IS_PHONE then
local uiScale = Instance.new("UIScale")
uiScale.Scale = 0.6
uiScale.Parent = topbar
end
local messageGui = ui:WaitForChild("GameJoin")
local message = messageGui:WaitForChild("Message")
local message = gameJoin:WaitForChild("Message")
local exitOverride = gameJoin:WaitForChild("ExitOverride")
local partWatch = nil
local partQueue = {}
@ -60,96 +54,39 @@ local messageFormat = "Bricks: %d Connectors: %d"
---------------------------------------------------------------------
local fakeLoadTime = TeleportService:GetTeleportSetting("FakeLoadTime")
local function onDescendantAdded(desc)
if desc:IsA("BasePart") and not desc:IsA("Terrain") then
if not CollectionService:HasTag(desc, "AxisPart") and desc.Name ~= "__negatepart" then
desc.LocalTransparencyModifier = 1
partQueue[#partQueue + 1] = desc
end
elseif desc:IsA("Decal") then
desc.LocalTransparencyModifier = 1
end
end
if fakeLoadTime then
local descendants = workspace:GetDescendants()
for _,desc in pairs(descendants) do
onDescendantAdded(desc)
end
partWatch = workspace.DescendantAdded:Connect(onDescendantAdded)
end
---------------------------------------------------------------------
local camera = workspace.CurrentCamera
camera.CameraType = "Follow"
camera.CameraSubject = workspace
messageGui.Visible = true
gameJoin.Visible = true
local bricks = 0
local connectors = 0
local lastUpdate = 0
local done = false
while not game:IsLoaded() do
game.Loaded:Wait()
end
local function stepBrickConnectorStatus()
if fakeLoadTime then
wait(math.random() / 4)
for i = 1, math.random(30, 50) do
local part = table.remove(partQueue)
if part then
bricks = bricks + 1
connectors = connectors + #part:GetJoints()
part.LocalTransparencyModifier = 0
for _,v in pairs(part:GetDescendants()) do
if v:IsA("Decal") then
v.LocalTransparencyModifier = 0
end
end
end
end
done = (#partQueue == 0)
else
wait()
done = game:IsLoaded()
if not player.Character then
camera.CameraSubject = nil
message.Text = "Requesting character..."
local requestCharacter = ReplicatedStorage:WaitForChild("RequestCharacter")
requestCharacter:FireServer()
message.Text = "Waiting for character..."
while not player.Character do
player.CharacterAdded:Wait()
end
end
while not done do
stepBrickConnectorStatus()
message.Text = messageFormat:format(bricks, connectors)
if not exitOverride.Visible then
gameJoin.Visible = false
end
if partWatch then
partWatch:Disconnect()
partWatch = nil
end
camera.CameraType = "Custom"
camera.CameraSubject = player.Character
camera.CameraSubject = nil
message.Text = "Requesting character..."
wait(1)
local rep = game:GetService("ReplicatedStorage")
local requestCharacter = rep:WaitForChild("RequestCharacter")
requestCharacter:FireServer()
message.Text = "Waiting for character..."
while not player.Character do
player.CharacterAdded:Wait()
wait()
end
messageGui.Visible = false
camera.CameraType = "Custom"
script:Destroy()

View File

@ -1,50 +1,45 @@
{
"name": "MainModule",
"name": "SNZ_SHARED",
"tree":
{
"$path": "shared.lua",
"ReplicatedStorage":
"$className": "Folder",
"MainModule":
{
"$className": "Folder",
"ItemData": { "$path": "Shared/ItemData" },
"AssetUtil": { "$path": "Shared/AssetUtil.lua" },
"BrickColors": { "$path": "Shared/BrickColors.lua" },
"PlaceData": { "$path": "Shared/PlaceData.lua" },
"$path": "shared.lua",
"SharedScripts":
"ReplicatedStorage":
{
"$className": "Folder",
"Sky": {"$path": "Client/Sky"},
"Moon": {"$path": "Client/Moon"},
"SunRays": {"$path": "Client/SunRays"},
"ItemData": { "$path": "Shared/ItemData" },
"AssetUtil": { "$path": "Shared/AssetUtil.lua" },
"BrickColors": { "$path": "Shared/BrickColors.lua" },
"PlaceData": { "$path": "Shared/PlaceData.lua" },
"Mouse": {"$path": "UI/Mouse/Mouse.client.lua" },
"FpsCap": {"$path": "Client/FpsCap.client.lua" },
"LensFlare": {"$path": "Client/LensFlare.client.lua"}
}
},
"ServerScriptService":
{
"$className": "Folder",
"LightingConfig":
"SharedScripts":
{
"$className": "Folder",
"Sky": {"$path": "Client/Sky"},
"Moon": {"$path": "Client/Moon"},
"SunRays": {"$path": "Client/SunRays"},
"Mouse": {"$path": "UI/Mouse/Mouse.client.lua" },
"FpsCap": {"$path": "Client/FpsCap.client.lua" },
"LensFlare": {"$path": "Client/LensFlare.client.lua"}
}
},
"ServerStorage":
{
"$path": "Server/Scripts/LightingConfig.server.lua"
}
},
"ServerStorage":
{
"$className": "Folder",
"PlayerDataStore":
{
"$path": "Server/Resources/PlayerDataStore.lua"
"$className": "Folder",
"PlayerDataStore":
{
"$path": "Server/Resources/PlayerDataStore.lua"
}
}
}
}