Skip to content

Instantly share code, notes, and snippets.

@BigBang1112
Created June 5, 2023 02:05
Show Gist options
  • Save BigBang1112/3a42ff1036445838bf1e2b339b196451 to your computer and use it in GitHub Desktop.
Save BigBang1112/3a42ff1036445838bf1e2b339b196451 to your computer and use it in GitHub Desktop.
My ManiaScript library from 2020 that does something
#Include "MathLib" as MathLib
#Struct SBlockInfo {
Text Name;
Int3 Coord;
}
#Struct STriggerBlock {
Vec3 Position; // Centered
Vec3 Size;
Int3 NearestCoord;
}
#Struct STriggerSphere {
Vec3 Position;
Real Radius;
}
#Struct STriggerList {
STriggerBlock[] Blocks;
STriggerSphere[] Spheres;
}
#Struct SLocation {
Boolean Enabled;
Boolean IsWaypoint;
Vec3 Position;
Real Detector;
SBlockInfo[] Blocks;
STriggerList Triggers;
Text[Text] Attributes;
}
#Struct SLocationEvent {
Text Type;
Text Name;
CUser User;
SLocation Location;
Int3 Coord;
Integer Block; // Which block-type trigger triggered this event
Integer Sphere; // Which sphere-type trigger triggered this event
}
#Struct SLocationState {
Text Name;
SLocation Location;
CUser User;
}
#Struct SSphere {
Vec3 Position;
Real Radius;
}
#Const C_Detector_Default 3.
#Const C_Event_OnTriggerEnter "OnTriggerEnter"
#Const C_Event_OnTriggerLeave "OnTriggerLeave"
#Const C_Event_OnTrigger "OnTrigger"
declare SLocation[Text] Location;
declare CMapEditorPlugin UsedPlugin;
declare CMap UsedMap;
/*Vec3 GetBlockSize(Text _Environment) {
declare Vec3 Size;
if(_Environment == "Canyon")
Size = <64.,8.,64.>;
else if(_Environment == "Stadium"
|| _Environment == "Valley"
|| _Environment == "Lagoon")
Size = <32.,8.,32.>;
else if(_Environment == "Storm")
Size = <16.,8.,16.>;
return Size;
}*/
STriggerBlock GetTriggerBlockFromEvent(SLocationEvent _Event) {
declare STriggerBlock Trigger;
if(_Event.Block == -1) return Trigger;
return _Event.Location.Triggers.Blocks[_Event.Block];
}
Int3 GetNearestCoordFromVec3(CMapEditorPlugin _Plugin, Vec3 _Position) {
declare BlockSize = _Plugin.CollectionSquareSize;
declare GroundY = _Plugin.CollectionGroundY;
declare Height = _Plugin.CollectionSquareHeight;
return <MathLib::NearestInteger(_Position.X / BlockSize) - 1,
MathLib::NearestInteger(_Position.Y / Height) + GroundY - 1,
MathLib::NearestInteger(_Position.Z / BlockSize) - 1>;
}
SBlockInfo ToSBlockInfo(CBlock _Block) {
declare SBlockInfo B;
B.Name = _Block.BlockModel.Name;
B.Coord = _Block.Coord;
return B;
}
Boolean OpenRead(CMap _Map) {
if(_Map == Null) return False;
UsedPlugin = Null;
UsedMap = _Map;
declare metadata Text LOCATION for _Map;
return Location.fromjson(LOCATION);
}
Boolean OpenEdit(CMapEditorPlugin _Plugin) {
if(_Plugin == Null) return False;
UsedPlugin = _Plugin;
UsedMap = Null;
declare metadata Text LOCATION for UsedPlugin.Map;
return Location.fromjson(LOCATION);
}
Boolean Save() {
if(UsedPlugin == Null) return False;
declare metadata Text LOCATION for UsedPlugin.Map;
LOCATION = Location.tojson();
return True;
}
Boolean AddLocation(Text _Name, CBlock[] _Blocks, Text[Text] _Attributes) {
if(UsedPlugin == Null) return False;
declare SLocation L;
L.Enabled = True;
L.Detector = C_Detector_Default;
foreach(Block in _Blocks) {
L.Blocks.add(ToSBlockInfo(Block));
L.Position += UsedPlugin.GetVec3FromCoord(Block.Coord);
}
L.Position = <L.Position.X/_Blocks.count, L.Position.Y/_Blocks.count, L.Position.Z/_Blocks.count>;
foreach(Block in _Blocks) {
declare STriggerBlock T;
T.Size = <UsedPlugin.CollectionSquareSize, UsedPlugin.CollectionSquareHeight, UsedPlugin.CollectionSquareSize>;
foreach(Unit in Block.BlockUnits) {
T.NearestCoord = Block.Coord + Unit.AbsoluteOffset;
T.Position = L.Position - UsedPlugin.GetVec3FromCoord(T.NearestCoord);
L.Triggers.Blocks.add(T);
}
}
foreach(Name => Value in _Attributes)
L.Attributes[Name] = Value;
Location[_Name] = L;
return True;
}
Boolean AddLocation(Text _Name, CBlock[] _Blocks) {
return AddLocation(_Name, _Blocks, []);
}
Boolean AddLocation(Text _Name, CBlock _Block, Text[Text] _Attributes) {
return AddLocation(_Name, [_Block], _Attributes);
}
Boolean AddLocation(Text _Name, CBlock _Block) {
return AddLocation(_Name, _Block, []);
}
Boolean AddLocation(Text _Name, SSphere[] _Spheres, Text[Text] _Attributes) {
declare Text Environment;
if(UsedPlugin != Null) Environment = UsedPlugin.Map.CollectionName;
else if(UsedMap != Null) Environment = UsedMap.CollectionName;
else return False;
declare SLocation L;
L.Enabled = True;
L.Detector = C_Detector_Default;
foreach(Sphere in _Spheres)
L.Position += Sphere.Position;
L.Position = <L.Position.X/_Spheres.count, L.Position.Y/_Spheres.count, L.Position.Z/_Spheres.count>;
foreach(Sphere in _Spheres) {
declare STriggerSphere T;
T.Position = L.Position - Sphere.Position;
T.Radius = Sphere.Radius;
L.Triggers.Spheres.add(T);
}
foreach(Name => Value in _Attributes)
L.Attributes[Name] = Value;
Location[_Name] = L;
return True;
}
Boolean AddLocation(Text _Name, SSphere[] _Spheres) {
return AddLocation(_Name, _Spheres, []);
}
Boolean AddLocation(Text _Name, SSphere _Sphere, Text[Text] _Attributes) {
return AddLocation(_Name, [_Sphere], _Attributes);
}
Boolean AddLocation(Text _Name, SSphere _Sphere) {
return AddLocation(_Name, _Sphere, []);
}
SLocation Get(Text _Name) {
return Location[_Name];
}
Void Private_EnteringTrigger(Text _LocName, SLocation _Loc, CUser _User, Integer _Block, Integer _Sphere) {
declare SLocationState[] LocationStates for This; // Declares Trigger state system
declare SLocationEvent[] LocationEvents for This; // Declares Trigger event system
declare SLocationEvent Event;
Event.Name = _LocName;
Event.Location = _Loc;
Event.Block = _Block;
Event.Sphere = _Sphere;
Event.User <=> _User;
declare AlreadyIn = False; // It is expected at the beginning that the user is not touching the trigger
foreach(State in LocationStates) { // Goes through each available trigger state
AlreadyIn = State.Name == _LocName && State.User == _User; // If the user is colliding with this trigger already
if(AlreadyIn) break; // Leaves the foreach if it's true
}
if(!AlreadyIn) { // If the user is not in (but realistically he is)
declare SLocationState State;
State.Name = _LocName;
State.Location = _Loc;
State.User <=> _User; // Reference the user
LocationStates.add(State); // A new Trigger state is added
Event.Type = C_Event_OnTriggerEnter; // This event is considered OnTriggerEnter
LocationEvents.add(Event); // And added to the event list
}
Event.Type = C_Event_OnTrigger; // Right after Trigger enter (if the Trigger is new), loopy event OnTrigger is called
LocationEvents.add(Event); // And added
}
Void Private_LeavingTrigger(Text _LocName, SLocation _Loc, CUser _User, Integer _Block, Integer _Sphere) {
declare SLocationState[] LocationStates for This; // Declares Trigger state system
foreach(Index => State in LocationStates) {
declare AlreadyIn = State.Name == _LocName && State.User == _User;
if(AlreadyIn) {
declare SLocationEvent[] LocationEvents for This; // Declares Trigger event system
declare SLocationEvent Event;
Event.Name = _LocName;
Event.Type = C_Event_OnTriggerLeave;
Event.Location = _Loc;
Event.Block = _Block;
Event.Sphere = _Sphere;
LocationEvents.add(Event);
declare Removed = LocationStates.removekey(Index);
break;
}
}
}
Void CheckTrigger(CUser _User, Vec3 _Detector) {
foreach(Name => Loc in Location) {
if(Loc.Enabled) {
if(Loc.IsWaypoint) {
}
else {
declare DoesTrigger = False;
foreach(Index => Trigger in Loc.Triggers.Blocks) {
declare SLocationState[] LocationStates for This; // Declares Trigger state system
declare AbsolutePos = Loc.Position - Trigger.Position; // Absolute trigger position
if(_Detector.X-Loc.Detector <= AbsolutePos.X+Trigger.Size.X/2.
&& _Detector.X+Loc.Detector >= AbsolutePos.X-Trigger.Size.X/2.
&& _Detector.Y-Loc.Detector <= AbsolutePos.Y+Trigger.Size.Y/2.
&& _Detector.Y+Loc.Detector >= AbsolutePos.Y-Trigger.Size.Y/2.
&& _Detector.Z-Loc.Detector <= AbsolutePos.Z+Trigger.Size.Z/2.
&& _Detector.Z+Loc.Detector >= AbsolutePos.Z-Trigger.Size.Z/2.) {
Private_EnteringTrigger(Name, Loc, _User, Index, -1);
DoesTrigger = True;
}
}
foreach(Index => Trigger in Loc.Triggers.Spheres) {
declare SLocationState[] LocationStates for This; // Declares Trigger state system
declare AbsolutePos = Loc.Position + Trigger.Position; // Absolute trigger position
if(MathLib::Distance(_Detector, AbsolutePos) < Loc.Detector + Trigger.Radius) { // If the trigger sphere is touching the detector range
Private_EnteringTrigger(Name, Loc, _User, -1, Index);
DoesTrigger = True;
}
}
if(!DoesTrigger) {
Private_LeavingTrigger(Name, Loc, _User, -1, -1);
}
}
}
}
}
Void Loop(CTmMode _Mode) {
foreach(Player in _Mode.Players) {
CheckTrigger(Player.User, Player.Position);
}
declare SLocationEvent[] LocationEvents for This;
foreach(Event in LocationEvents) {
}
LocationEvents.clear();
}
Void Loop(CMapEditorPlugin _Plugin) {
CheckTrigger(_Plugin.LocalUser, _Plugin.CameraTargetPosition);
declare SLocationEvent[] LocationEvents for This;
foreach(Event in LocationEvents) {
}
LocationEvents.clear();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment