0

я создаю ASI плагин для игры GTA SA, и у меня есть 11 ошибок, решение которых я не могу выяснить. Будьте любезны, помогите пожалуйста...

Rubbish.cpp

#include "stdafx.h"
#include "Rubbish.h"

#include "Game.h" #include "TxdStore.h" #include "Camera.h" #include "World.h" #include "Weather.h" #include "Timer.h" #include "Vehicle.h" #include "debugmenu_public.h"

    int CRubbish::RubbishVisibility;
    bool CRubbish::bRubbishInvisible;
    COneSheet CRubbish::aSheets[CRubbish::NUMSHEETS];
    COneSheet CRubbish::StartEmptyList, CRubbish::EndEmptyList;
    COneSheet CRubbish::StartStaticsList, CRubbish::EndStaticsList;
    COneSheet CRubbish::StartMoversList, CRubbish::EndMoversList;
    RwTexture* CRubbish::gpRubbishTexture[4];

    void
        COneSheet::AddToList(COneSheet * list)
    {
        this->prev = list;
        this->next = list->next;
        list->next = this;
        this->next->prev = this;
    }

    void
        COneSheet::RemoveFromList(void)
    {
        this->next->prev = this->prev;
        this->prev->next = this->next;
    }

    void
        CRubbish::Init(void)
    {
        int i;
        for (i = 0; i < NUMSHEETS; i++) {
            aSheets[i].type = 0;
            if (i == 0)
                aSheets[i].prev = &StartEmptyList;
            else
                aSheets[i].prev = &aSheets[i - 1];
            if (i + 1 >= NUMSHEETS)
                aSheets[i].next = &EndEmptyList;
            else
                aSheets[i].next = &aSheets[i + 1];
        }

        StartEmptyList.next = &aSheets[0];
        StartEmptyList.prev = NULL;
        EndEmptyList.next = NULL;
        EndEmptyList.prev = &aSheets[NUMSHEETS - 1];

        StartStaticsList.next = &EndStaticsList;
        StartStaticsList.prev = NULL;
        EndStaticsList.next = NULL;
        CRubbish::EndStaticsList.prev = &CRubbish::StartStaticsList;

        CRubbish::StartMoversList.next = &CRubbish::EndMoversList;
        CRubbish::StartMoversList.prev = NULL;
        CRubbish::EndMoversList.next = NULL;
        CRubbish::EndMoversList.prev = &CRubbish::StartMoversList;
        CTxdStore::PushCurrentTxd();
        CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("rubbish"));
        gpRubbishTexture[0] = RwTextureRead("gameleaf01_64", NULL);
        gpRubbishTexture[1] = RwTextureRead("gameleaf02_64", NULL);
        gpRubbishTexture[2] = RwTextureRead("newspaper01_64", NULL);
        gpRubbishTexture[3] = RwTextureRead("newspaper02_64", NULL);
        CTxdStore::PopCurrentTxd();
        CRubbish::RubbishVisibility = 255;
        CRubbish::bRubbishInvisible = false;
    }

    void
        CRubbish::StirUp(CVehicle * vehicle)
    {
        if ((CTimer::m_FrameCounter ^ vehicle->RandomSeed) & 3)
            return;

        CVector campos = TheCamera.GetCoords();
        CVector vehpos = vehicle->GetCoords();
        if (abs(campos.x - vehpos.x) > 20.0f ||
            abs(campos.y - vehpos.y) > 20.0f)
            return;

        CVector speedvec = vehicle->GetLinearVelocity();
        if (abs(speedvec.x) <= 0.05f && abs(speedvec.y) <= 0.05f)
            return;

        float speed = CVector(speedvec.x, speedvec.y, 0.0f).Magnitude();
        if (speed <= 0.05f)
            return;

        CVector* up = vehicle->GetMatrix()->GetUp();
        CVector* right = vehicle->GetMatrix()->GetRight();
        float speed_dot_up = speedvec.x * up->x + speedvec.y * up->y;

        CColModel* col = CModelInfo::GetModelInfo(vehicle->GetModelIndex())->GetColModel();
        float length = col->boundingBox.vecMax.y;
        float width = col->boundingBox.vecMax.x;

        COneSheet* sheet, * next;
        for (sheet = StartStaticsList.next; sheet != &EndStaticsList; sheet = next) {
            next = sheet->next;
            float dx = sheet->vec1.x - vehpos.x;
            float dy = sheet->vec1.y - vehpos.y;
            float dist_dot_up = dx * up->x + dy * up->y;
            float dist_dot_right = abs(dx * right->x + dy * right->y);

            // this is all weird
            if (speed_dot_up > 0.0f && dist_dot_up < -0.5f * length && dist_dot_up > -1.5f * length ||
                speed_dot_up <= 0.0f && dist_dot_up > 0.5f * length && dist_dot_up < 1.5f * length) {
                float s = dist_dot_right >= width ? 0.5f * speed : speed;
                if (dist_dot_right < 1.5f * width && s > 0.05f) {
                    sheet->type = 2;
                    sheet->movementType = s <= 0.15f ? 1 : 2;
                    sheet->duration = 2000;
                    float l = sqrt(speedvec.x * speedvec.x + speedvec.y * speedvec.y);
                    sheet->moveOffsetX = speedvec.x / l * speed * 25.0f;
                    sheet->moveOffsetY = speedvec.y / l * speed * 25.0f;
                    sheet->moveOffsetZ = speed * 3.0f;
                    sheet->startTime = CTimer::m_snTimeInMilliseconds;
                    sheet->moveTargetZ = CWorld::FindGroundZFor3DCoord(
                        sheet->vec1.x + sheet->moveOffsetX,
                        sheet->vec1.y + sheet->moveOffsetY,
                        sheet->vec1.z + 3.0f, NULL, NULL) + 0.1f;
                    sheet->RemoveFromList();
                    sheet->AddToList(&StartMoversList);
                }
            }
        }
    }

    static uint8 rand8(void) { return rand(); }

    WRAPPER int CCullZones__FindAttributesForCoors(float x, float y, float z) { EAXJMP(0x72D970); }

    static float
        FindGroundForRubbish(float x, float y, float z, bool* success)
    {
        float groundz = CWorld::FindGroundZFor3DCoord(x, y, z, success, NULL);
        return groundz;

        // get the water to work right :/
        //  if(CWaterLevel::GetWaterLevel(x, y, z, &waterz, false, NULL))
        //      ;
    }

    void
        CRubbish::Update(void)
    {
        COneSheet* sheet;

        if (bRubbishInvisible) {
            RubbishVisibility -= 5;
            if (RubbishVisibility < 0)
                RubbishVisibility = 0;
        }
        else {
            RubbishVisibility += 5;
            if (RubbishVisibility > 255)
                RubbishVisibility = 255;
        }

        CVector campos = TheCamera.GetCoords();

        // Generate new sheets
        sheet = StartEmptyList.next;
        if (sheet != &EndEmptyList) {
            float radius = rand8() / 255.0f + 23.0f;
            float angle;
            uint8 r = rand8();
            if (r & 1)
                angle = rand8() / 255.0f * M_PI * 2.0f;
            else
                angle = (r - 128) / 160.0f + TheCamera.Orientation;
            sheet->vec1.x = sin(angle) * radius + campos.x;
            sheet->vec1.y = cos(angle) * radius + campos.y;
            bool foundGround;
            sheet->vec1.z = FindGroundForRubbish(sheet->vec1.x, sheet->vec1.y, campos.z, &foundGround) + 0.1f;
            if (foundGround) {
                sheet->angle = rand8() / 255.0f * M_PI * 2.0f;
                sheet->type = 1;
                if (CCullZones__FindAttributesForCoors(sheet->vec1.x, sheet->vec1.y, sheet->vec1.z) & 8)
                    sheet->zoneVisible1 = 0;
                else
                    sheet->zoneVisible1 = 1;
                sheet->RemoveFromList();
                sheet->AddToList(&StartStaticsList);
            }
        }

        static float movement[3][34] = {
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },

        { 0, 0.05, 0.12, 0.25, 0.42, 0.57, 0.68, 0.8, 0.86, 0.9, 0.93, 0.95, 0.96, 0.97, 0.98, 0.99, 1, // XY movemnt
        0.15, 0.35, 0.6, 0.9, 1.2, 1.25, 1.3, 1.2, 1.1, 0.95, 0.8, 0.6, 0.45, 0.3, 0.2, 0.1, 0 },   // Z movement

        { 0, 0.05, 0.12, 0.25, 0.42, 0.57, 0.68, 0.8, 0.95, 1.1, 1.15, 1.18, 1.15, 1.1, 1.05, 1.03, 1,
        0.15, 0.35, 0.6, 0.9, 1.2, 1.25, 1.3, 1.2, 1.1, 0.95, 0.8, 0.6, 0.45, 0.3, 0.2, 0.1, 0 }
        };
        // Update Movers
        COneSheet* next;
        for (sheet = StartMoversList.next; sheet != &EndMoversList; sheet = next) {
            next = sheet->next;
            int t = CTimer::m_snTimeInMilliseconds - sheet->startTime;
            if (t < sheet->duration) {
                int step = 16 * t / sheet->duration;    // 16 steps
                float stepInterp = (t - sheet->duration / 16.0f * step) / (sheet->duration / 16.0f);    // interpolation along step
                float interp = (float)t / sheet->duration;  // interpolation along total animation
                float moveMult = stepInterp * movement[sheet->movementType][step + 1] +
                    (1.0f - stepInterp) * movement[sheet->movementType][step];
                float moveMultZ = stepInterp * movement[sheet->movementType][step + 1 + 17] +
                    (1.0f - stepInterp) * movement[sheet->movementType][step + 17];

                sheet->vec2.x = sheet->vec1.x + sheet->moveOffsetX * moveMult;
                sheet->vec2.y = sheet->vec1.y + sheet->moveOffsetY * moveMult;
                sheet->vec2.z = interp * sheet->moveTargetZ + (1.0f - interp) * sheet->vec1.z +
                    sheet->moveOffsetZ * moveMultZ;
                sheet->angle += CTimer::ms_fTimeStep / 25.0f;
                if (sheet->angle > 2 * M_PI)
                    sheet->angle -= 2 * M_PI;
            }
            else {
                // Move done, make static again
                sheet->vec1.x += sheet->moveOffsetX;
                sheet->vec1.y += sheet->moveOffsetY;
                sheet->vec1.z = sheet->moveTargetZ;
                sheet->type = 1;
                sheet->zoneVisible1 = sheet->zoneVisible2;
                sheet->RemoveFromList();
                sheet->AddToList(&StartStaticsList);
            }
        }

        int freq;
        if (CWeather::Wind < 0.1f)
            freq = 0x1F;
        else if (CWeather::Wind < 0.4f)
            freq = 7;
        else if (CWeather::Wind < 0.7f)
            freq = 1;
        else
            freq = 0;

        // Turn Statics into Movers
        if ((CTimer::m_FrameCounter & freq) == 0) {
            int i = rand() & (NUMSHEETS - 1);
            sheet = &aSheets[i];
            if (sheet->type == 1) {
                sheet->startTime = CTimer::m_snTimeInMilliseconds;
                sheet->duration = CWeather::Wind * 1500.0f + 1000.0f;
                sheet->moveOffsetZ = 0.2f;
                sheet->moveOffsetX = CWeather::Wind * 3.0f;
                sheet->moveOffsetY = CWeather::Wind * 3.0f;
                bool foundGround;
                sheet->moveTargetZ = FindGroundForRubbish(sheet->vec1.x + sheet->moveOffsetX, sheet->vec1.y + sheet->moveOffsetY, sheet->vec1.z, &foundGround) + 0.1f;
                if (CCullZones__FindAttributesForCoors(sheet->vec1.x + sheet->moveOffsetX, sheet->vec1.y + sheet->moveOffsetY, sheet->moveTargetZ) & 8)
                    sheet->zoneVisible2 = 0;
                else
                    sheet->zoneVisible2 = 1;
                if (foundGround) {
                    sheet->type = 2;
                    sheet->movementType = 1;
                    sheet->RemoveFromList();
                    sheet->AddToList(&StartMoversList);
                }
            }
        }

        // Remove sheets that are too far away
        // Actually only two per frame
        int i;
        for (i = 0; i < NUMSHEETS; i++) {
            if (aSheets[i].type != 1)
                continue;
            if (aSheets[i].vec1.DistanceXY(campos) > 24.0f) {
                aSheets[i].type = 0;
                aSheets[i].RemoveFromList();
                aSheets[i].AddToList(&StartEmptyList);
            }
        }
    }

    static int TempBufferIndicesStored;
    static int TempBufferVerticesStored;
    static RwIm3DVertex TempVertexBuffer[512];
    static RwImVertexIndex TempBufferRenderIndexList[1024];

    void
        CRubbish::Render(void)
    {
        if (RubbishVisibility == 0 || CGame::currArea > 0)
            return;

        int alphafunc;
        RwRenderStateGet(rwRENDERSTATEALPHATESTFUNCTION, &alphafunc);
        RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTION, (void*)rwALPHATESTFUNCTIONALWAYS);

        RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, 0);
        RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
        RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);

        int textype;
        for (textype = 0; textype < 4; textype++) {
            if (textype < 3)
                RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRubbishTexture[textype]));
            TempBufferIndicesStored = 0;
            TempBufferVerticesStored = 0;

            for (COneSheet* sheet = &aSheets[textype * (NUMSHEETS / 4)];
                sheet < &aSheets[(textype + 1) * (NUMSHEETS / 4)];
                sheet++) {
                if (sheet->type == 0)
                    continue;

                int alpha = 100;
                CVector pos;
                if (sheet->type == 1) {
                    pos = sheet->vec1;
                    if (!sheet->zoneVisible1)
                        alpha = 0;
                }
                else {
                    pos = sheet->vec2;
                    if (!sheet->zoneVisible1 || !sheet->zoneVisible2) {
                        float t = (float)(CTimer::m_snTimeInMilliseconds - sheet->startTime) / sheet->duration;
                        float f1 = sheet->zoneVisible1 ? 1.0f - t : 0.0f;
                        float f2 = sheet->zoneVisible2 ? t : 0.0f;
                        alpha = 100 * (f1 + f2);
                    }
                }

                float dist = pos.DistanceXY(TheCamera.GetCoords());
                if (dist > 23.0f)
                    continue;
                if (dist > 20.0f)
                    alpha -= alpha * (dist - 20.0f) / (23.0f - 20.0f);

                float vx1, vx2;
                float vy1, vy2;
                static float sizes[4] = { 0.4, 0.8, 0.3, 0.3 }; // all square in VCS

                vx1 = sin(sheet->angle) * sizes[textype];
                vy1 = cos(sheet->angle) * sizes[textype];
                vx2 = cos(sheet->angle) * sizes[textype];
                vy2 = -sin(sheet->angle) * sizes[textype];

                alpha = RubbishVisibility * alpha / 255;

                int i = TempBufferVerticesStored;
                RwIm3DVertexSetPos(&TempVertexBuffer[i + 0], pos.x + vx1 + vx2, pos.y + vy1 + vy2, pos.z);
                RwIm3DVertexSetPos(&TempVertexBuffer[i + 1], pos.x + vx1 - vx2, pos.y + vy1 - vy2, pos.z);
                RwIm3DVertexSetPos(&TempVertexBuffer[i + 2], pos.x - vx1 + vx2, pos.y - vy1 + vy2, pos.z);
                RwIm3DVertexSetPos(&TempVertexBuffer[i + 3], pos.x - vx1 - vx2, pos.y - vy1 - vy2, pos.z);
                RwIm3DVertexSetRGBA(&TempVertexBuffer[i + 0], 255, 255, 255, alpha);
                RwIm3DVertexSetRGBA(&TempVertexBuffer[i + 1], 255, 255, 255, alpha);
                RwIm3DVertexSetRGBA(&TempVertexBuffer[i + 2], 255, 255, 255, alpha);
                RwIm3DVertexSetRGBA(&TempVertexBuffer[i + 3], 255, 255, 255, alpha);
                RwIm3DVertexSetU(&TempVertexBuffer[i + 0], 0.0f);
                RwIm3DVertexSetV(&TempVertexBuffer[i + 0], 0.0f);
                RwIm3DVertexSetU(&TempVertexBuffer[i + 1], 1.0f);
                RwIm3DVertexSetV(&TempVertexBuffer[i + 1], 0.0f);
                RwIm3DVertexSetU(&TempVertexBuffer[i + 2], 0.0f);
                RwIm3DVertexSetV(&TempVertexBuffer[i + 2], 1.0f);
                RwIm3DVertexSetU(&TempVertexBuffer[i + 3], 1.0f);
                RwIm3DVertexSetV(&TempVertexBuffer[i + 3], 1.0f);

                TempBufferRenderIndexList[TempBufferIndicesStored++] = TempBufferVerticesStored + 0;
                TempBufferRenderIndexList[TempBufferIndicesStored++] = TempBufferVerticesStored + 1;
                TempBufferRenderIndexList[TempBufferIndicesStored++] = TempBufferVerticesStored + 2;
                TempBufferRenderIndexList[TempBufferIndicesStored++] = TempBufferVerticesStored + 1;
                TempBufferRenderIndexList[TempBufferIndicesStored++] = TempBufferVerticesStored + 3;
                TempBufferRenderIndexList[TempBufferIndicesStored++] = TempBufferVerticesStored + 2;
                TempBufferVerticesStored += 4;
            }

            if (TempBufferIndicesStored) {
                if (RwIm3DTransform(TempVertexBuffer, TempBufferVerticesStored, NULL, rwIM3D_VERTEXUV)) {
                    RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
                    RwIm3DEnd();
                }
            }
        }

        RwRenderStateSet(rwRENDERSTATEFOGENABLE, 0);
        RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, 0);
        RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);

        RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTION, (void*)alphafunc);
    }

    void
        CRubbish::SetVisibility(bool v)
    {
        bRubbishInvisible = !v;
    }

    static StaticPatcher Patcher([]() {
        Memory::InjectHook(0x7204C0, CRubbish::SetVisibility, PATCH_JUMP);
        if (DebugMenuLoad()) {
            DebugMenuAddVarBool8("Rendering", "Rubbish invisible", (int8*)&CRubbish::bRubbishInvisible, NULL);
        }
        });

rubbish.h

#ifndef __RUBBISH
#define __RUBBISH

struct COneSheet { CVector vec1; CVector vec2; float moveTargetZ; int8 type; int8 movementType; int32 startTime; int32 duration; float moveOffsetZ; float moveOffsetX; float moveOffsetY; float angle; int8 zoneVisible1; int8 zoneVisible2; int8 unk72; int8 unk73; COneSheet next; COneSheet prev;

void AddToList(COneSheet *list);
void RemoveFromList(void);

};

class CVehicle;

class CRubbish { public: // MUST be a power of 2 enum { NUMSHEETS = 32 };

static int RubbishVisibility;
static bool bRubbishInvisible;
static COneSheet aSheets[NUMSHEETS];
static COneSheet StartEmptyList, EndEmptyList;
static COneSheet StartStaticsList, EndStaticsList;
static COneSheet StartMoversList, EndMoversList;
static RwTexture *gpRubbishTexture[4];

static void Init(void);
static void Update(void);
static void StirUp(CVehicle *vehicle);
static void Render(void);
static void SetVisibility(bool v);

};

#endif

Ошибки:

Rubbish.obj : error LNK2001: неразрешенный внешний символ _RwIm3DEnd.
Rubbish.obj : error LNK2001: неразрешенный внешний символ _RwTextureRead.
Rubbish.obj : error LNK2001: неразрешенный внешний символ _RwIm3DRenderIndexedPrimitive.
Rubbish.obj : error LNK2001: неразрешенный внешний символ _RwEngineInstance.
Rubbish.obj : error LNK2001: неразрешенный внешний символ "public: __thiscall StaticPatcher::StaticPatcher(void (__cdecl*)(void))" (??0StaticPatcher@@QAE@P6AXXZ@Z).
Rubbish.obj : error LNK2001: неразрешенный внешний символ "public: static class CBaseModelInfo * * CModelInfo::ms_modelInfoPtrs" (?ms_modelInfoPtrs@CModelInfo@@2QAPAVCBaseModelInfo@@A).
Rubbish.obj : error LNK2001: неразрешенный внешний символ _RwIm3DTransform.
Rubbish.obj : error LNK2001: неразрешенный внешний символ "public: static int & CTimer::m_snTimeInMilliseconds" (?m_snTimeInMilliseconds@CTimer@@2AAHA).
Rubbish.obj : error LNK2001: неразрешенный внешний символ "public: static double __cdecl CWorld::FindGroundZFor3DCoord(float,float,float,bool *,class CEntity * *)" (?FindGroundZFor3DCoord@CWorld@@SANMMMPA_NPAPAVCEntity@@@Z).
Rubbish.obj : error LNK2001: неразрешенный внешний символ _gDebugMenuAPI.
O:\GTA San Andreas\scripts\vcrubbish.SA.asi : fatal error LNK1120: неразрешенных внешних элементов: 10
  • В ошибках явно говорится про неразрешенный внешний символ. Ну, например, _RwIm3DEnd — это библиотека DirectX, включите заголовочный файл d3d9.h. Если SA — это San Andreas, кажется 9-ая версия dx актуальна была на тот момент. – DiMithras Jul 29 '23 at 18:39
  • это не библиотека directx, это штука renderware, #include d3d9.h также не помогла – TheArtemMaps Jul 29 '23 at 19:34

0 Answers0