diff --git a/meta/win/lib/msvc/x86/assimp-vc143-mt.lib b/meta/win/lib/msvc/x86/assimp-vc143-mt.lib new file mode 100644 index 00000000..6a21fe5d Binary files /dev/null and b/meta/win/lib/msvc/x86/assimp-vc143-mt.lib differ diff --git a/source/Engine/Bytecode/ScriptEntity.cpp b/source/Engine/Bytecode/ScriptEntity.cpp index 27d92ca8..bcd8073a 100644 --- a/source/Engine/Bytecode/ScriptEntity.cpp +++ b/source/Engine/Bytecode/ScriptEntity.cpp @@ -1386,6 +1386,51 @@ PUBLIC STATIC VMValue ScriptEntity::VM_GetHitboxFromSprite(int argCount, VMValue return NULL_VAL; } +/*** + * \method ReturnHitboxFromSprite + * \desc Gets the hitbox in the specified sprite's animation, frame and hitbox ID. + * \param sprite (Sprite): The sprite. + * \param animation (Integer): The animation index. + * \param frame (Integer): The frame index. + * \param hitbox (Integer): The hitbox ID. + * \return Returns an array containing the hitbox top, left, right and bottom sides in that order. + * \ns Instance + */ +PUBLIC STATIC VMValue ScriptEntity::VM_ReturnHitboxFromSprite(int argCount, VMValue* args, Uint32 threadID) { + StandardLibrary::CheckArgCount(argCount, 5); + ScriptEntity* self = GET_ENTITY(0); + ISprite* sprite = GET_ARG(1, GetSprite); + int animation = GET_ARG(2, GetInteger); + int frame = GET_ARG(3, GetInteger); + int hitbox = GET_ARG(4, GetInteger); + + if (!self || !sprite) + return NULL_VAL; + + if (!(animation > -1 && (size_t)animation < sprite->Animations.size())) { + ScriptManager::Threads[threadID].ThrowRuntimeError(false, "Animation %d is not in bounds of sprite.", animation); + return NULL_VAL; + } + if (!(frame > -1 && (size_t)frame < sprite->Animations[animation].Frames.size())) { + ScriptManager::Threads[threadID].ThrowRuntimeError(false, "Frame %d is not in bounds of animation %d.", frame, animation); + return NULL_VAL; + } + + AnimFrame frameO = sprite->Animations[animation].Frames[frame]; + + if (!(hitbox > -1 && hitbox < frameO.BoxCount)) { + // ScriptManager::Threads[threadID].ThrowRuntimeError(false, "Hitbox %d is not in bounds of frame %d.", hitbox, frame); + return NULL_VAL; + } + + CollisionBox box = frameO.Boxes[hitbox]; + ObjArray* array = NewArray(); + array->Values->push_back(DECIMAL_VAL((float)box.Left)); + array->Values->push_back(DECIMAL_VAL((float)box.Top)); + array->Values->push_back(DECIMAL_VAL((float)box.Right)); + array->Values->push_back(DECIMAL_VAL((float)box.Bottom)); + return OBJECT_VAL(array); +} /*** * \method CollideWithObject diff --git a/source/Engine/Bytecode/ScriptManager.cpp b/source/Engine/Bytecode/ScriptManager.cpp index 4c392176..5d079b16 100644 --- a/source/Engine/Bytecode/ScriptManager.cpp +++ b/source/Engine/Bytecode/ScriptManager.cpp @@ -862,6 +862,7 @@ PUBLIC STATIC void ScriptManager::AddNativeObjectFunctions(ObjClass* klass) { DEF_NATIVE(SetAnimation); DEF_NATIVE(ResetAnimation); DEF_NATIVE(GetHitboxFromSprite); + DEF_NATIVE(ReturnHitboxFromSprite); DEF_NATIVE(AddToRegistry); DEF_NATIVE(RemoveFromRegistry); DEF_NATIVE(CollidedWithObject); diff --git a/source/Engine/Bytecode/StandardLibrary.cpp b/source/Engine/Bytecode/StandardLibrary.cpp index 9d89a44d..184d3e96 100644 --- a/source/Engine/Bytecode/StandardLibrary.cpp +++ b/source/Engine/Bytecode/StandardLibrary.cpp @@ -6860,6 +6860,18 @@ VMValue Math_ACos256(int argCount, VMValue* args, Uint32 threadID) { CHECK_ARGCOUNT(1); return INTEGER_VAL(Math::ACos256(GET_ARG(0, GetInteger))); } +/*** + * RSDK.Math.ATan2 + * \desc Returns the arc tangent of a position. + * \param x (Decimal): X value of the position. + * \param y (Decimal): Y value of the position. + * \return The arc tangent of the position. + * \ns RSDK.Math + */ +VMValue Math_ATan2(int argCount, VMValue* args, Uint32 threadID) { + CHECK_ARGCOUNT(1); + return INTEGER_VAL(Math::ArcTanLookup((int)(GET_ARG(0, GetDecimal) * 65536.0f), (int)(GET_ARG(1, GetDecimal) * 65536.0f))); +} /*** * RSDK.Math.RadianToInteger * \desc Gets the integer conversion of a radian, based on 256. @@ -7962,7 +7974,7 @@ VMValue Number_AsDecimal(int argCount, VMValue* args, Uint32 threadID) { VMValue Object_Loaded(int argCount, VMValue* args, Uint32 threadID) { CHECK_ARGCOUNT(1); - char* objectName = GET_ARG(0, GetString); + char* objectName = GET_ARG(0, GetString); return INTEGER_VAL(!!Scene::ObjectLists->Exists(Scene::ObjectLists->HashFunction(objectName, strlen(objectName)))); } diff --git a/source/Engine/Math/Math.cpp b/source/Engine/Math/Math.cpp index 056232c9..f60499fb 100644 --- a/source/Engine/Math/Math.cpp +++ b/source/Engine/Math/Math.cpp @@ -23,7 +23,7 @@ int Tan256LookupTable[0x100]; int ASin256LookupTable[0x100]; int ACos256LookupTable[0x100]; -int ArcTan256LookupTable[0x100 * 0x100]; +unsigned int ArcTan256LookupTable[0x100 * 0x100]; int randSeed = 0; @@ -130,6 +130,15 @@ PUBLIC STATIC void Math::CalculateTrigAngles() { ASin256LookupTable[i] = (int)((asinf(i / 255.0) * 128.0) / R_PI); ACos256LookupTable[i] = (int)((acosf(i / 255.0) * 128.0) / R_PI); } + + for (int y = 0; y < 0x100; y++) { + unsigned int* arcTan = (unsigned int*)&ArcTan256LookupTable[y]; + + for (int x = 0; x < 0x100; x++) { + *arcTan = (int)(float)((float)atan2((float)y, x) * 40.743664f); + arcTan += 0x100; + } + } } PUBLIC STATIC int Math::Sin1024(int angle) { return Sin1024LookupTable[angle & 0x3FF]; @@ -200,6 +209,33 @@ PUBLIC STATIC int Math::ACos256(int angle) { return -ACos256LookupTable[-angle]; return ACos256LookupTable[angle]; } +PUBLIC STATIC unsigned int Math::ArcTanLookup(int X, int Y) { + int x = abs(X); + int y = abs(Y); + + if (x <= y) { + while (y > 0xFF) { + x >>= 4; + y >>= 4; + } + } + else { + while (x > 0xFF) { + x >>= 4; + y >>= 4; + } + } + if (X <= 0) { + if (Y <= 0) + return ArcTan256LookupTable[(x << 8) + y] + 0x80; + else + return 0x80 - ArcTan256LookupTable[(x << 8) + y]; + } + else if (Y <= 0) + return -ArcTan256LookupTable[(x << 8) + y]; + else + return ArcTan256LookupTable[(x << 8) + y]; +} // help PUBLIC STATIC int Math::CeilPOT(int n) {