Участник
-
Автор темы
- #261
Я, кстати, тоже догадался, что с референсами в функциях типа WorldToScreen будет нечисто
По поводу партиклменеджера наревёрсил вчера:
Код:class CDOTAParticleManager : public VClass { public: enum class ParticleAttachment_t : int { PATTACH_INVALID = -1, PATTACH_ABSORIGIN = 0, PATTACH_ABSORIGIN_FOLLOW = 1, PATTACH_CUSTOMORIGIN = 2, PATTACH_CUSTOMORIGIN_FOLLOW = 3, PATTACH_POINT = 4, PATTACH_POINT_FOLLOW = 5, PATTACH_EYES_FOLLOW = 6, PATTACH_OVERHEAD_FOLLOW = 7, PATTACH_WORLDORIGIN = 8, PATTACH_ROOTBONE_FOLLOW = 9, PATTACH_RENDERORIGIN_FOLLOW = 10, PATTACH_MAIN_VIEW = 11, PATTACH_WATERWAKE = 12, PATTACH_CENTER_FOLLOW = 13, PATTACH_CUSTOM_GAME_STATE_1 = 14, PATTACH_HEALTHBAR = 15, MAX_PATTACH_TYPES = 16, }; struct ParticleInfo { const char* particleName; ParticleAttachment_t attachmentType; BaseEntity* ent; private: void* unk0 = nullptr; void* unk1 = nullptr; void* unk2 = nullptr; void* unk3 = nullptr; void* unk4 = nullptr; }; class Particle : public VClass { public: VClass* GetParticleCollection() { return Member<VClass*>(0x20); } void SetControlPoint(int idx, Vector3* pos) { auto coll = GetParticleCollection(); coll->GetVFunc(0x80 / 8)(coll, idx, pos); } }; struct ParticleContainer { Particle* GetParticle() { return *(Particle**)((uintptr_t)this + 0x10); } }; int GetParticleCount() { return Member<uint32_t>(0x80); } ParticleContainer** GetParticleArray() { return Member<ParticleContainer**>(0x88); } uint32_t GetHandle() { return Member<uint32_t>(0x98); } void IncHandle() { *(uint32_t*)((uintptr_t)this + 0x98) = GetHandle() + 1; } Particle* CreateParticle(ParticleInfo info) { IncHandle(); GetVFunc(7)(this, GetHandle(), info); return GetParticleArray()[GetParticleCount() - 1]->GetParticle(); } };
Посмотреть вложение 236577Код:// да, знаю, на криэйтпартикл надо нормальную обёртку написать CDOTAParticleManager::ParticleInfo info{}; info.attachmentType = CDOTAParticleManager::ParticleAttachment_t::PATTACH_ABSORIGIN_FOLLOW; info.particleName = "particles/ui_mouseactions/selected_ring.vpcf"; info.ent = (BaseEntity*)assignedHero; Vector3 color{ 255,0,255 }; Vector3 radius{ 1200, 255, 0 }; auto particle = Globals::ParticleManager->CreateParticle(info); particle->SetControlPoint(1, &color); particle->SetControlPoint(2, &radius);
Ещё вопрос по поводу самых ходовых партиклей. Хотелось бы подобие selection_ring.vpcf, но со свечением(как когда рендж атаки вышки показывает), в мелонити VBE такое вроде бы у друга видел
Посмотреть вложение 236578
C++:
coll->GetVFunc(0x80 / 8)(coll, idx, pos);
2) вместо просто числа 16 юзай символическую константу(простыми словами - переменную с ясным названием) чтобы ясно и понятно было. дополнительно рекоммендуется задокументировать комментами если возможно откуда ты это взял(например "перед функцией МояФунка" или "после функции Тест123" или "внутри функции блаблабла есть вызов этой функи с индексом 16" или "функция внутри имеет хреф на строку блаблабла") чтобы потом когда индекс апдейтнется ты мог бы его заново легко найти(т.к. у тебя описаны шаги для нахождения этого индекса)
/* inside function: string xref "blablabla" */
constexpr SetControlPoint_VFTABLE_INDEX = 16;
...
GetVFunc(SetControlPoint_VFTABLE_INDEX) blablabla
3) не юзай GetVFunc и потом вызов. юзай сразу CallVFunc которая внутри юзает GetVFunc и вызывает сразу функу
4)
C++:
struct ParticleContainer {
Particle* GetParticle() {
return *(Particle**)((uintptr_t)this + 0x10);
}
};
5) cl_particle_log_creates true в помощь тебе квар. врубаешь его жмешь альт и смотришь какие партикли там создает