Skip to content

Commit

Permalink
Made some Math functions respect the number type
Browse files Browse the repository at this point in the history
  • Loading branch information
Axanery committed Jun 25, 2024
1 parent 3c47e9b commit 4959089
Showing 1 changed file with 14 additions and 269 deletions.
283 changes: 14 additions & 269 deletions source/Engine/Bytecode/StandardLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6675,7 +6675,7 @@ VMValue Math_Direction(int argCount, VMValue* args, Uint32 threadID) {
*/
VMValue Math_Abs(int argCount, VMValue* args, Uint32 threadID) {
CHECK_ARGCOUNT(1);
return DECIMAL_VAL(Math::Abs(GET_ARG(0, GetDecimal)));
return IS_INTEGER(args[0]) ? INTEGER_VAL((int)Math::Abs(GET_ARG(0, GetDecimal))) : DECIMAL_VAL(Math::Abs(GET_ARG(0, GetDecimal)));
}
/***
* Math.Min
Expand All @@ -6687,8 +6687,10 @@ VMValue Math_Abs(int argCount, VMValue* args, Uint32 threadID) {
*/
VMValue Math_Min(int argCount, VMValue* args, Uint32 threadID) {
CHECK_ARGCOUNT(2);
// respect the type of number
return DECIMAL_VAL(Math::Min(GET_ARG(0, GetDecimal), GET_ARG(1, GetDecimal)));
if (IS_INTEGER(args[0]) && IS_INTEGER(args[1]))
return INTEGER_VAL((int)Math::Min(GET_ARG(0, GetDecimal), GET_ARG(1, GetDecimal)));
else
return DECIMAL_VAL(Math::Min(GET_ARG(0, GetDecimal), GET_ARG(1, GetDecimal)));
}
/***
* Math.Max
Expand All @@ -6700,7 +6702,10 @@ VMValue Math_Min(int argCount, VMValue* args, Uint32 threadID) {
*/
VMValue Math_Max(int argCount, VMValue* args, Uint32 threadID) {
CHECK_ARGCOUNT(2);
return DECIMAL_VAL(Math::Max(GET_ARG(0, GetDecimal), GET_ARG(1, GetDecimal)));
if (IS_INTEGER(args[0]) && IS_INTEGER(args[1]))
return INTEGER_VAL((int)Math::Max(GET_ARG(0, GetDecimal), GET_ARG(1, GetDecimal)));
else
return DECIMAL_VAL(Math::Max(GET_ARG(0, GetDecimal), GET_ARG(1, GetDecimal)));
}
/***
* Math.Clamp
Expand All @@ -6713,7 +6718,10 @@ VMValue Math_Max(int argCount, VMValue* args, Uint32 threadID) {
*/
VMValue Math_Clamp(int argCount, VMValue* args, Uint32 threadID) {
CHECK_ARGCOUNT(3);
return DECIMAL_VAL(Math::Clamp(GET_ARG(0, GetDecimal), GET_ARG(1, GetDecimal), GET_ARG(2, GetDecimal)));
if (IS_INTEGER(args[0]) && IS_INTEGER(args[1]) && IS_INTEGER(args[2]))
return INTEGER_VAL((int)Math::Clamp(GET_ARG(0, GetDecimal), GET_ARG(1, GetDecimal), GET_ARG(2, GetDecimal)));
else
return DECIMAL_VAL(Math::Clamp(GET_ARG(0, GetDecimal), GET_ARG(1, GetDecimal), GET_ARG(2, GetDecimal)));
}
/***
* Math.ToFixed
Expand Down Expand Up @@ -7109,7 +7117,7 @@ VMValue Math_RadianToInteger(int argCount, VMValue* args, Uint32 threadID) {
}
/***
* RSDK.Math.IntegerToRadian
* \desc Gets the radia Decimal conversion of an integer, based on 256.
* \desc Gets the radian Decimal conversion of an integer, based on 256.
* \param integer (Integer): Integer value to convert.
* \return A radia Decimal value of the converted integer.
* \ns RSDK.Math
Expand Down Expand Up @@ -9116,269 +9124,6 @@ VMValue Resources_ReadAllText(int argCount, VMValue* args, Uint32 threadID) {
// #region Scene
#define CHECK_TILE_LAYER_POS_BOUNDS() if (layer < 0 || layer >= (int)Scene::Layers.size() || x < 0 || y < 0 || x >= Scene::Layers[layer].Width || y >= Scene::Layers[layer].Height) return NULL_VAL;

/***
* Scene.ProcessObjectMovement
* \desc Processes movement of an instance with an outer hitbox and an inner hitboxe.
* \param entity (Instance): The instance to move.
* \param outer (Array): Array containing the outer hitbox.
* \param inner (Array): Array containing the inner hitbox.
* \ns Scene
*/
VMValue Scene_ProcessObjectMovement(int argCount, VMValue* args, Uint32 threadID) {
CHECK_ARGCOUNT(3);
ObjInstance* entity = GET_ARG(0, GetInstance);
ObjArray* outer = GET_ARG(1, GetArray);
ObjArray* inner = GET_ARG(2, GetArray);

CollisionBox outerBox;
CollisionBox innerBox;

if (entity && outer && inner) {
auto ent = (Entity*)entity->EntityPtr;

outerBox.Left = (int)AS_DECIMAL((*outer->Values)[0]);
outerBox.Top = (int)AS_DECIMAL((*outer->Values)[1]);
outerBox.Right = (int)AS_DECIMAL((*outer->Values)[2]);
outerBox.Bottom = (int)AS_DECIMAL((*outer->Values)[3]);

innerBox.Left = (int)AS_DECIMAL((*inner->Values)[0]);
innerBox.Top = (int)AS_DECIMAL((*inner->Values)[1]);
innerBox.Right = (int)AS_DECIMAL((*inner->Values)[2]);
innerBox.Bottom = (int)AS_DECIMAL((*inner->Values)[3]);
Scene::ProcessObjectMovement(ent, &outerBox, &innerBox);
}
return NULL_VAL;
}
/***
* Scene.ObjectTileCollision
* \desc Checks tile collision based on where an instance should check.
* \param entity (Instance): The instance to base the values on.
* \param cLayers (Bitfield): Which layers the entity can collide with.
* \param cMode (Integer): Collision mode of the entity (floor, left wall, roof, right wall).
* \param cPlane (Integer): Collision plane to get the collision of (A or B).
* \param xOffset (Number): How far from the entity's X value to start from.
* \param yOffset (Number): How far from the entity's Y value to start from.
* \param setPos (Boolean): Whether to set the entity's position if collision is found.
* \return Returns whether the instance has collided with a tile.
* \ns Scene
*/
VMValue Scene_ObjectTileCollision(int argCount, VMValue* args, Uint32 threadID) {
CHECK_ARGCOUNT(7);
ObjInstance* entity = GET_ARG(0, GetInstance);
int cLayers = GET_ARG(1, GetInteger);
int cMode = GET_ARG(2, GetInteger);
int cPlane = GET_ARG(3, GetInteger);
int xOffset = (int)GET_ARG(4, GetDecimal);
int yOffset = (int)GET_ARG(5, GetDecimal);
int setPos = GET_ARG(6, GetInteger);

auto ent = (Entity*)entity->EntityPtr;

return INTEGER_VAL(Scene::ObjectTileCollision(ent, cLayers, cMode, cPlane, xOffset, yOffset, setPos));
}
/***
* Scene.ObjectTileGrip
* \desc Keeps an instance gripped to tile collision based on where an instance should check.
* \param entity (Instance): The instance to move.
* \param cLayers (Bitfield): Which layers the entity can collide with.
* \param cMode (Integer): Collision mode of the entity (floor, left wall, roof, right wall).
* \param cPlane (Integer): Collision plane to get the collision of (A or B).
* \param xOffset (Decimal): How far from the entity's X value to start from.
* \param yOffset (Decimal): How far from the entity's Y value to start from.
* \param tolerance (Decimal): How far of a tolerance the entity should check for.
* \return Returns whether to grip the instance.
* \ns Scene
*/
VMValue Scene_ObjectTileGrip(int argCount, VMValue* args, Uint32 threadID) {
CHECK_ARGCOUNT(7);
ObjInstance* entity = GET_ARG(0, GetInstance);
int cLayers = GET_ARG(1, GetInteger);
int cMode = GET_ARG(2, GetInteger);
int cPlane = GET_ARG(3, GetInteger);
int xOffset = (int)GET_ARG(4, GetDecimal);
int yOffset = (int)GET_ARG(5, GetDecimal);
float tolerance = GET_ARG(6, GetDecimal);

auto ent = (Entity*)entity->EntityPtr;

return INTEGER_VAL(Scene::ObjectTileGrip(ent, cLayers, cMode, cPlane, xOffset, yOffset, tolerance));
}
/***
* Scene.CheckObjectCollisionTouch
* \desc Checks if an instance is touching another instance with their respective hitboxes.
* \param thisEntity (Instance): The first instance to check.
* \param thisHitbox (Array): Array containing the first entity's hitbox.
* \param otherEntity (Instance): The other instance to check.
* \param otherHitbox (Array): Array containing the other entity's hitbox.
* \return Returns a Boolean value whether the entities are touching.
* \ns Scene
*/
VMValue Scene_CheckObjectCollisionTouch(int argCount, VMValue* args, Uint32 threadID) {
CHECK_ARGCOUNT(4);
ObjInstance* thisEntity = GET_ARG(0, GetInstance);
ObjArray* thisHitbox = GET_ARG(1, GetArray);
ObjInstance* otherEntity = GET_ARG(2, GetInstance);
ObjArray* otherHitbox = GET_ARG(3, GetArray);

auto thisEnt = (Entity*)thisEntity->EntityPtr;
auto otherEnt = (Entity*)otherEntity->EntityPtr;

CollisionBox thisBox;
CollisionBox otherBox;

if (IS_INTEGER((*thisHitbox->Values)[0])) {
thisBox.Left = AS_INTEGER((*thisHitbox->Values)[0]);
thisBox.Top = AS_INTEGER((*thisHitbox->Values)[1]);
thisBox.Right = AS_INTEGER((*thisHitbox->Values)[2]);
thisBox.Bottom = AS_INTEGER((*thisHitbox->Values)[3]);
}
else {
thisBox.Left = (int)AS_DECIMAL((*thisHitbox->Values)[0]);
thisBox.Top = (int)AS_DECIMAL((*thisHitbox->Values)[1]);
thisBox.Right = (int)AS_DECIMAL((*thisHitbox->Values)[2]);
thisBox.Bottom = (int)AS_DECIMAL((*thisHitbox->Values)[3]);
}

if (IS_INTEGER((*otherHitbox->Values)[0])) {
otherBox.Left = AS_INTEGER((*otherHitbox->Values)[0]);
otherBox.Top = AS_INTEGER((*otherHitbox->Values)[1]);
otherBox.Right = AS_INTEGER((*otherHitbox->Values)[2]);
otherBox.Bottom = AS_INTEGER((*otherHitbox->Values)[3]);
}
else {
otherBox.Left = (int)AS_DECIMAL((*otherHitbox->Values)[0]);
otherBox.Top = (int)AS_DECIMAL((*otherHitbox->Values)[1]);
otherBox.Right = (int)AS_DECIMAL((*otherHitbox->Values)[2]);
otherBox.Bottom = (int)AS_DECIMAL((*otherHitbox->Values)[3]);
}
return INTEGER_VAL(!!Scene::CheckObjectCollisionTouch(thisEnt, &thisBox, otherEnt, &otherBox));
}
/***
* Scene.CheckObjectCollisionCircle
* \desc Checks if an instance is touching another instance with within their respective radii.
* \param thisEnity (Instance): The first instance to check.
* \param thisRadius (Decimal): Radius of the first entity to check.
* \param otherEntity (Instance): The other instance to check.
* \param otherRadius (Array): Radius of the other entity to check.
* \return Returns a Boolean value whether the entities have collided.
* \ns Scene
*/
VMValue Scene_CheckObjectCollisionCircle(int argCount, VMValue* args, Uint32 threadID) {
CHECK_ARGCOUNT(4);
ObjInstance* thisEntity = GET_ARG(0, GetInstance);
float thisRadius = GET_ARG(1, GetDecimal);
ObjInstance* otherEntity = GET_ARG(2, GetInstance);
float otherRadius = GET_ARG(3, GetDecimal);

auto thisEnt = (Entity*)thisEntity->EntityPtr;
auto otherEnt = (Entity*)otherEntity->EntityPtr;

return INTEGER_VAL(!!Scene::CheckObjectCollisionCircle(thisEnt, thisRadius, otherEnt, otherRadius));
}
/***
* Scene.CheckObjectCollisionBox
* \desc Checks if an instance is touching another instance with their respective hitboxes and sets the values of the other instance if specified.
* \param thisEnity (Instance): The first instance to check.
* \param thisHitbox (Array): Array containing the first entity's hitbox.
* \param otherEntity (Instance): The other instance to check.
* \param otherHitbox (Array): Array containing the other entity's hitbox.
* \param setValues (Boolean): Whether to set the values of the other entity.
* \return Returns the side the entities are colliding on.
* \ns Scene
*/
VMValue Scene_CheckObjectCollisionBox(int argCount, VMValue* args, Uint32 threadID) {
CHECK_ARGCOUNT(5);
ObjInstance* thisEntity = GET_ARG(0, GetInstance);
ObjArray* thisHitbox = GET_ARG(1, GetArray);
ObjInstance* otherEntity = GET_ARG(2, GetInstance);
ObjArray* otherHitbox = GET_ARG(3, GetArray);
bool setValues = !!GET_ARG(4, GetInteger);

auto thisEnt = (Entity*)thisEntity->EntityPtr;
auto otherEnt = (Entity*)otherEntity->EntityPtr;

CollisionBox thisBox;
CollisionBox otherBox;

if (IS_INTEGER((*thisHitbox->Values)[0])) {
thisBox.Left = AS_INTEGER((*thisHitbox->Values)[0]);
thisBox.Top = AS_INTEGER((*thisHitbox->Values)[1]);
thisBox.Right = AS_INTEGER((*thisHitbox->Values)[2]);
thisBox.Bottom = AS_INTEGER((*thisHitbox->Values)[3]);
}
else {
thisBox.Left = (int)AS_DECIMAL((*thisHitbox->Values)[0]);
thisBox.Top = (int)AS_DECIMAL((*thisHitbox->Values)[1]);
thisBox.Right = (int)AS_DECIMAL((*thisHitbox->Values)[2]);
thisBox.Bottom = (int)AS_DECIMAL((*thisHitbox->Values)[3]);
}

if (IS_INTEGER((*otherHitbox->Values)[0])) {
otherBox.Left = AS_INTEGER((*otherHitbox->Values)[0]);
otherBox.Top = AS_INTEGER((*otherHitbox->Values)[1]);
otherBox.Right = AS_INTEGER((*otherHitbox->Values)[2]);
otherBox.Bottom = AS_INTEGER((*otherHitbox->Values)[3]);
}
else {
otherBox.Left = (int)AS_DECIMAL((*otherHitbox->Values)[0]);
otherBox.Top = (int)AS_DECIMAL((*otherHitbox->Values)[1]);
otherBox.Right = (int)AS_DECIMAL((*otherHitbox->Values)[2]);
otherBox.Bottom = (int)AS_DECIMAL((*otherHitbox->Values)[3]);
}
return INTEGER_VAL(Scene::CheckObjectCollisionBox(thisEnt, &thisBox, otherEnt, &otherBox, setValues));
}
/***
* Scene.CheckObjectCollisionPlatform
* \desc Checks if an instance is touching the top of another instance with their respective hitboxes and sets the values of the other instance if specified.
* \param thisEnity (Instance): The first instance to check.
* \param thisHitbox (Array): Array containing the first entity's hitbox.
* \param otherEntity (Instance): The other instance to check whether it is on top of the first instance.
* \param otherHitbox (Array): Array containing the other entity's hitbox.
* \param setValues (Boolean): Whether to set the values of the other entity.
* \return Returns a Boolean value whether the entities have collided.
* \ns Scene
*/
VMValue Scene_CheckObjectCollisionPlatform(int argCount, VMValue* args, Uint32 threadID) {
CHECK_ARGCOUNT(5);
ObjInstance* thisEntity = GET_ARG(0, GetInstance);
ObjArray* thisHitbox = GET_ARG(1, GetArray);
ObjInstance* otherEntity = GET_ARG(2, GetInstance);
ObjArray* otherHitbox = GET_ARG(3, GetArray);
bool setValues = !!GET_ARG(4, GetInteger);

auto thisEnt = (Entity*)thisEntity->EntityPtr;
auto otherEnt = (Entity*)otherEntity->EntityPtr;

CollisionBox thisBox;
CollisionBox otherBox;

if (IS_INTEGER((*thisHitbox->Values)[0])) {
thisBox.Left = AS_INTEGER((*thisHitbox->Values)[0]);
thisBox.Top = AS_INTEGER((*thisHitbox->Values)[1]);
thisBox.Right = AS_INTEGER((*thisHitbox->Values)[2]);
thisBox.Bottom = AS_INTEGER((*thisHitbox->Values)[3]);
}
else {
thisBox.Left = (int)AS_DECIMAL((*thisHitbox->Values)[0]);
thisBox.Top = (int)AS_DECIMAL((*thisHitbox->Values)[1]);
thisBox.Right = (int)AS_DECIMAL((*thisHitbox->Values)[2]);
thisBox.Bottom = (int)AS_DECIMAL((*thisHitbox->Values)[3]);
}

if (IS_INTEGER((*otherHitbox->Values)[0])) {
otherBox.Left = AS_INTEGER((*otherHitbox->Values)[0]);
otherBox.Top = AS_INTEGER((*otherHitbox->Values)[1]);
otherBox.Right = AS_INTEGER((*otherHitbox->Values)[2]);
otherBox.Bottom = AS_INTEGER((*otherHitbox->Values)[3]);
}
else {
otherBox.Left = (int)AS_DECIMAL((*otherHitbox->Values)[0]);
otherBox.Top = (int)AS_DECIMAL((*otherHitbox->Values)[1]);
otherBox.Right = (int)AS_DECIMAL((*otherHitbox->Values)[2]);
otherBox.Bottom = (int)AS_DECIMAL((*otherHitbox->Values)[3]);
}
return INTEGER_VAL(!!Scene::CheckObjectCollisionPlatform(thisEnt, &thisBox, otherEnt, &otherBox, setValues));
}
/***
* Scene.Load
* \desc Changes the active scene. If a path to a resource is provided, the active scene is changed to the one in the specified resource file. Otherwise, the active scene is changed to the currently set entry in the scene list, if it exists (see <linkto ref="SceneList"></linkto>.)
Expand Down

0 comments on commit 4959089

Please sign in to comment.