You are not logged in.
А что странного? В коде он так же вызывается (см. 57BA5F - единственное место вызова).
Присоединяюсь, у нас 10 минут до нового года.
Всем счастья, здоровья и успехов в постижении самого трудного!
Заменил. Вылет остался. В чём у меня проблема, кто-нибудь может ответить?
Место вылета:
http://ru-script.3dn.ru/publ/sozdanie_d … 18-1-0-206
А у меня как-то по-другому это сделано? Где у меня ошибка подскажите.
Привет, народ! Сколько лет тут не был, но как симэн взялся за санник, решил заглянуть снова .
К делу. Пытаюсь своими силами через c++ вывести текстуру на экран из определённого TXD файла.
За основу взял небезызвестный gta_dll, к процессу игры подключаюсь путём подмены vorbisFile. Всё стандартно, вобщем.
Чудеса начинаются, когда я пытаюсь загрузить текстуру и попытаться отрисовать её по нажатию кнопки.
В самом верху:
CTexture* achievementGetTexture;
Далее, три процедуры отвечающие за загрузку, освобождение и отрисовку текстуры:
void LoadTextures() { int slot = txdStore.AddTxdSlot("achiv"); txdStore.LoadTxd(slot, "MODELS\\ACHIEV.TXD"); txdStore.AddRef(slot); txdStore.PushCurrentTxd(); txdStore.SetCurrentTxd(slot); achievementGetTexture->Load("ac_box", NULL); txdStore.PopCurrentTxd(); debug("TEXTURE: %x", achievementGetTexture); debug("Textures loaded"); } void ReleaseTextures() { if ( achievementGetTexture ) { achievementGetTexture->Clean(); achievementGetTexture = NULL; } int achievementGetTextureSlotIndex = CTxdStore::FindTxdSlot("achiv"); txdStore.RemoveTxdSlot(achievementGetTextureSlotIndex); debug("Textures released"); } void Update_Hook() { // Draw texture on demand. while ( GetAsyncKeyState(0x09) ) achievementGetTexture->DrawTexturedRect(&RwRect2D(_width(0), _height(448), _width(280), _height(188)), &RwRGBA(255, 255, 255, 255)); }
Где-то в DllMain:
call(0x5BD765, &LoadTextures, PATCH_CALL); call(0x53BBCB, &ReleaseTextures, PATCH_CALL); call(0x53BFAE, &Update_Hook, PATCH_CALL);
Собственно, проблема: при нажатии 0x09 (Tab) игра вылетает. Вылетает из-за того, что почему-то текстура не грузится в мой achievementGetTexture. Вот лог:
20:27:17.680 CTXDSTORE::ADDTXDSLOT([achiv])
20:27:17.681 CTXDSTORE::LOADTXD([4], [MODELS\ACHIEV.TXD])
20:27:17.697 CTXDSTORE::ADDREF([4])
20:27:17.697 CTXDSTORE::PUSHCURRENTTXD
20:27:17.697 CTXDSTORE::SETCURRENTTXD([4])
20:27:17.697 CTEXTURE::LOAD([ac_box], [(null)])
20:27:17.697 CTXDSTORE::POPCURRENTTXD
20:27:17.697 TEXTURE: 0 <-- sic!
20:27:17.697 Textures loaded
20:27:25.692 CTXDSTORE::FINDTXDSLOT([achiv])
20:27:25.692 CTXDSTORE::REMOVETXDSLOT([4])
20:27:25.692 Textures released
20:27:26.092 Log closed
Теперь самое главное: CTexture.h/.cpp, CTxdStore.h.cpp и RW.h/.cpp с определениями текстур и TxdStore.
#define FUNC_CTexture__DrawTexturedRect 0x728350 #define FUNC_CTexture__Load 0x7272B0 #define FUNC_CTexture__Reload 0x727270 #define FUNC_CTexture__Clean 0x727240 class CTexture { private: RwTexture* texture; public: CTexture() : texture(NULL) { }; void DrawTexturedRect(RwRect2D* pos, RwRGBA* color); void Load(const char* name, const char* maskName); void Clean(); void Reload(const char* name); void Reload(const char* name, const char* maskName); RwTexture* GetTexture() { return texture; }; };
#include "StdAfx.h" void CTexture::DrawTexturedRect(RwRect2D* pos, RwRGBA* color) { debug("CTEXTURE::DRAWTEXTUREDRECT([%.3f %.3f %.3f %.3f], [%i %i %i %i])", pos->x1, pos->y1, pos->x2, pos->y2, color->r, color->g, color->b, color->a); DWORD dwFunc = FUNC_CTexture__DrawTexturedRect; RwTexture* tex = GetTexture(); _asm { push color push pos mov ecx, tex call dwFunc } } void CTexture::Load(const char* name, const char* maskName) { debug("CTEXTURE::LOAD([%s], [%s])", name, maskName); DWORD dwFunc = FUNC_CTexture__Load; _asm { push maskName push name mov ecx, this call dwFunc mov [this], eax add esp, 8 } } void CTexture::Clean() { debug("CTEXTURE::CLEAN()"); DWORD dwFunc = FUNC_CTexture__Clean; _asm { mov ecx, this call dwFunc } } void CTexture::Reload(const char* name) { debug("CTEXTURE::RELOAD([%s])", name); if ( name ) { if ( texture ) { RwTexture::Destroy(texture); texture = NULL; } texture = RwTexture::Read(name, NULL); } } void CTexture::Reload(const char* name, const char* maskName) { debug("CTEXTURE::RELOAD([%s], [%s])", name, maskName); if ( name && maskName ) { if ( texture ) { RwTexture::Destroy(texture); texture = NULL; } texture = RwTexture::Read(name, maskName); } }
#define FUNC_CTxdStore__PushCurrentTxd 0x7316A0 #define FUNC_CTxdStore__PopCurrentTxd 0x7316B0 #define FUNC_CTxdStore__FindTxdSlot 0x731850 #define FUNC_CTxdStore__SetCurrentTxd 0x7319C0 #define FUNC_CTxdStore__AddTxdRef 0x731A00 #define FUNC_CTxdStore__AddTxdSlot 0x731C80 #define FUNC_CTxdStore__RemoveTxdSlot 0x731CD0 #define FUNC_CTxdStore__LoadTxd 0x7320B0 class CTxdStore { public: static void PushCurrentTxd(); static void PopCurrentTxd(); static int FindTxdSlot(const char *name); static void SetCurrentTxd(int slot); static void AddRef(int index); static int AddTxdSlot(const char* slotName); static void RemoveTxdSlot(int slot); static void LoadTxd(int slot, const char* fp); }; static CTxdStore txdStore;
#include "stdafx.h" void CTxdStore::PushCurrentTxd() { debug("CTXDSTORE::PUSHCURRENTTXD"); DWORD dwFunc = FUNC_CTxdStore__PushCurrentTxd; _asm call dwFunc } void CTxdStore::PopCurrentTxd() { debug("CTXDSTORE::POPCURRENTTXD"); DWORD dwFunc = FUNC_CTxdStore__PopCurrentTxd; _asm call dwFunc } int CTxdStore::FindTxdSlot(const char *name) { debug("CTXDSTORE::FINDTXDSLOT([%s])", name); DWORD dwFunc = FUNC_CTxdStore__FindTxdSlot; int result = 0; _asm { push name call dwFunc mov result, eax add esp, 4 } } void CTxdStore::SetCurrentTxd(int slot) { debug("CTXDSTORE::SETCURRENTTXD([%i])", slot); DWORD dwFunc = FUNC_CTxdStore__SetCurrentTxd; _asm { push slot call dwFunc } } void CTxdStore::AddRef(int index) { debug("CTXDSTORE::ADDREF([%i])", index); DWORD dwFunc = FUNC_CTxdStore__AddTxdRef; _asm { push index call dwFunc } } int CTxdStore::AddTxdSlot(const char* slotName) { debug("CTXDSTORE::ADDTXDSLOT([%s])", slotName); DWORD dwFunc = FUNC_CTxdStore__AddTxdSlot; int result = 0; _asm { push slotName call dwFunc mov result, eax add esp, 4 } } void CTxdStore::RemoveTxdSlot(int slot) { debug("CTXDSTORE::REMOVETXDSLOT([%i])", slot); DWORD dwFunc = FUNC_CTxdStore__RemoveTxdSlot; _asm { push slot call dwFunc } } void CTxdStore::LoadTxd(int slot, const char* fp) { debug("CTXDSTORE::LOADTXD([%i], [%s])", slot, fp); DWORD dwFunc = FUNC_CTxdStore__LoadTxd; _asm { push fp push slot call dwFunc } }
... #define FUNC_RwTexture__Destroy 0x7F3820 #define FUNC_RwTexture__Read 0x7F3AC0 struct RwTexture { RwRaster *raster; RwTexDictionary *txd; RwListEntry TXDList; char name[RW_TEXTURE_NAME_LENGTH]; char mask[RW_TEXTURE_NAME_LENGTH]; unsigned int flags; int refs; static void Destroy(RwTexture* texture); static RwTexture* Read(const char* name, const char* maskName); RwRaster* GetRaster() { return this->raster; }; }; ...
... void RwTexture::Destroy(RwTexture* texture) { DWORD dwFunc = FUNC_RwTexture__Destroy; _asm { push texture call dwFunc add esp, 4 } } RwTexture* RwTexture::Read(const char* name, const char* maskName) { DWORD dwFunc = FUNC_RwTexture__Read; RwTexture* result; _asm { push maskName push name call dwFunc add esp, 8 mov result, eax } return result; } ...
Всё хорошо, исходники бы ещё к этому делу...
Эдакая незамысловатая реклама ресурса либертисити...
Какое клео4... декомпилятора нормального ещё никто не придумал, а пока его не будет, ни о каком нормальном скриптинге говорить не приходится...
Какой ужас, я так ждал этот мод, а ты все мои надежды разрушил в один момент...
Object.Throw
Если у тебя конкретная машина (т.е. которая имеет хендл), то просто проверяй её здоровье. А если случайная машина, то тут затрудняюсь ответить.
Ну можно проверить: что, если, игрок стоит рядом с машиной и имеет опр. оружие в руках, то проверяем здоровье машины. Если игрок рядом с машиной с оружием и здоровье машины уменьшилось - игрок её атаковал.
А какие различия между Си+ и студией (которая использует этот самый си)
Обновлено до версии .9-RC1!
Ссылка такая же.
Они основаны на сорсах оригинальной игры
Только осторожней с ним, он 2009го года выпуска; сравнивай его с исходниками MTA и добавляй/поправляй где считаешь нужным
Вот что вышло:
{$CLEO .cs} 0000: NOP while true wait 0 if Player.Defined($PLAYER_CHAR) then 00BF: 20@ = current_time_hours, 21@ = current_time_minutes if 09DE: actor $PLAYER_ACTOR entering_car then 0AB5: $PLAYER_ACTOR 5@ 0@ // 5@ - íàøà ìàøèíà 0@ - áëèæ. ïåä (âîäèëà íàâåðíîå) if 5@ <> -1 then 01B4: $PLAYER_CHAR 0 0407: store_coords_to 10@ 11@ 12@ from_car 5@ with_offset 0 0 0 // 10@ - OX 11@ - OY 12@ - OZ 0407: store_coords_to 13@ 14@ 15@ from_car 5@ with_offset 0 0 0 0407: store_coords_to 16@ 17@ 18@ from_car 5@ with_offset 0 0 0 // ðàíäîìèçèðóåì îôôñåòû äëÿ êàìåðû 0208: 19@ = 2.5 15.8 0208: 20@ = -5.1 3.4 0208: 21@ = 2.0 4.0 0208: 22@ = -4.2 8.6 0208: 23@ = 1.3 7.2 // ïðèñâàèâàåì ýòè îôôñåòû 005B: 10@ += 19@ // camera coord[1] X 005B: 11@ += 20@ // camera coord[1] Y 005B: 12@ += 21@ // camera coord[1] Z 005B: 13@ += 22@ // camera coord[2] X 005B: 14@ += 23@ // camera coord[2] Y 15@ += 1.0 // camera coord[2] Z wait 500 015F: 10@ 11@ 12@ 0 0 0 0160: 16@ 17@ 18@ 2 wait 1500 015F: 13@ 14@ 15@ 0 0 0 0160: 16@ 17@ 18@ 2 wait 500 01B4: $PLAYER_CHAR 1 02EB: restore_camera_with_jumpcut 0373: set_camera_directly_behind_player 24@ += 1 end end end end end_thread
@Voron295 - проблема реально была в отсутствии endа :):):):):):):): спасибо
Когда он открывает дверь; должно меняться положение камеры, до тех пор, пока он не окажется в машине
Например?
Можно на мой вопрос ответить со 158й страницы?
Проверь, что будет если ввести всё, кроме "AGRU"
Существуют, поищи. А можно по существу? Что не так в скрипте?
На сколько я понял, он не отрабатывает то, что идёт после actor_entering car...