fonte para os novos bows e crossbows sem limite e com efeitos dinâmicos de ataque, as estruturas podem ser obtidas a partir da fonte do zteam e o carregamento do arquivo é feito por cada um.





CustomBows.cpp
Código:
#include "stdafx.h"
#include "BMD.h"
#include "CustomBows.h"
#include "Item.h"
#include "Object.h"
#include "Offset.h"
#include "Util.h"

DWORD IsBowItem = 0;
DWORD IsCrossItem = 0;
DWORD BowValue = 0x09C;
DWORD MaxBoneCount = 0x108;
DWORD WorldPosition = 0x0FC;

DWORD oCreateEffect = 0x6D9070; // 1.04D ENG
DWORD ReturnBowCode = 0x74A12E; // 1.04D ENG
DWORD BowPosition = 0x005CC8ED; // 1.04D ENG
DWORD NextBowPosition = 0x005CC92E; // 1.04D ENG
DWORD BowAddPlayerDimension_Offset = 0x0056617F; // 1.04D ENG

CustomBows gCustomBow;

#define Vector(a,b,c,d) {(d)[0]=a;(d)[1]=b;(d)[2]=c;}

void CustomBows::Load(CUSTOM_BOWS_DATA* info) // OK
{
	for (int n = 0; n < MAX_CUSTOM_BOWS; n++)
	{
		this->SetInfo(info[n]);
	}
}

void CustomBows::SetInfo(CUSTOM_BOWS_DATA info) // OK
{
	if (info.Index < 0 || info.Index >= MAX_CUSTOM_BOWS)
	{
		return;
	}

	this->m_CustomBow[info.Index] = info;
}

bool CustomBows::CheckBow(DWORD IsBowItem)
{
	for (int i = 0; i < 256; i++)
	{
		if (this->m_CustomBow[i].IsBow)
		{
			if (IsBowItem == GET_ITEM_MODEL(4, this->m_CustomBow[i].ItemId))
			{
				return true;
			}
		}
	}
	//--
	return false;
}

bool CustomBows::CheckCrossbow(DWORD IsBowItem)
{
	for (int i = 0; i < 256; i++)
	{
		if (this->m_CustomBow[i].IsCrossbow)
		{
			if (IsBowItem == GET_ITEM_MODEL(4, this->m_CustomBow[i].ItemId))
			{
				return true;
			}
		}
	}
	//--
	return false;
}

__declspec(naked) void cCrossPos()
{
	static DWORD Address1 = 0x00565994;
	static DWORD Address2 = 0x005659E7;
	_asm
	{
		Mov Ecx, Dword ptr ss : [ebp + 0x1C]
		Mov Dword ptr ss : [ebp + 0x1C], Ecx
		Mov IsCrossItem, Ecx
	}
	if (IsCrossItem >= ITEM2(4, 8) && IsCrossItem <= ITEM2(4, 14) || IsCrossItem == ITEM2(4, 16) || IsCrossItem == ITEM2(4, 18) || IsCrossItem == ITEM2(4, 19))//new
	{
		_asm{jmp Address1}
	}
	else if (gCustomBow.CheckCrossbow(IsCrossItem))
	{
		_asm{jmp Address1}
	}
	else
	{
		_asm{jmp Address2}
	}

}

void __declspec(naked) cBowAddInventoryPos()
{
	_asm
	{

		mov ecx,dword ptr ss:[ebp+0x8]
		mov dword ptr ss:[ebp+0x8],ecx
		mov IsBowItem,ecx
	}
	// ---
	if(IsBowItem == 0x0CAB)
	{	
		_asm{jmp BowPosition}
	}
	else if (gCustomBow.CheckBow(IsBowItem))
	{
		_asm{jmp BowPosition}
	}
	else
	{
		_asm{jmp NextBowPosition}
	}
}

void __declspec(naked) cBowAddPlayerDimension()
{
	DWORD ItemId;

	_asm
	{

		mov ecx, dword ptr ss : [ebp + 0x1c]
		mov dword ptr ss : [ebp + 0x1c], ecx
		mov ItemId, ecx
	}
	
	if (ItemId == 0x0CA7)
	{
		_asm
		{
			je ReturnLoad
		}
	}
	else if (gCustomBow.CheckBow(ItemId))
	{
		_asm
		{
			je ReturnLoad
		}
	}
	_asm
	{
		// ---
		ReturnLoad:
		// ---
		jmp BowAddPlayerDimension_Offset
	}
}

void CreateEffect(WORD Effecid, vec3_t VecPos, vec3_t WorldPos, vec3_t Color, int zero, DWORD Owner, short lpModel, BYTE a4, BYTE a5, int a6,int a7,int a8)
{
	sub_6D9070(Effecid, VecPos, WorldPos, Color, zero, Owner, lpModel, a4, a5, a6, a7, a8);
}

void CreateBowSkillEffect(DWORD lpObj, DWORD lpModel, DWORD Owner, BYTE a4, BYTE a5, WORD Skill)
{
	short Bow;
	short CrossBow;
	int EffectType;

	lpViewObj gObj = &*(ObjectPreview*)lpObj;
	lpModelObj gModel = &*(ObjectModel*)lpModel;

	vec3_t Color;
	vec3_t VecPos;
	vec3_t WorldPos;

	Vector(gModel->ColorR, gModel->ColorG, gModel->ColorB, Color);
	Vector(gModel->VecPosX, gModel->VecPosY, gModel->VecPosZ, VecPos);
	Vector(gModel->WorldPos.X, gModel->WorldPos.Y, gModel->WorldPos.Z, WorldPos);

	EffectType = 0;
	CrossBow = gObj->WeaponFirstSlot;
	Bow = gObj->WeaponSecondSlot;

	if (lpObj == oUserPreviewStruct)
	{
		CrossBow = *(short *)(oUserObjectStruct + 4672);
		Bow = *(short *)(oUserObjectStruct + 4779);

		if (CrossBow != -1)
			CrossBow += ITEM_BASE_MODEL;
		if (Bow != -1)
			Bow += ITEM_BASE_MODEL;
	}

	if (Skill == 52 || Skill == 416)
	{
		EffectType = 2;
		sub_6D6C20(85, lpModel, 0);
	}
	*(int*)0x8793730 = Skill;
	if (Skill == 51 || Skill == 424)
		sub_6D6C20(130, (DWORD)lpModel, 0);
	if (a5 == 2)
		EffectType = 99;
	if (Skill == 46)
	{
		CreateEffect(365, VecPos, WorldPos, Color, 0, Owner, *(short *)(lpModel + 44), a4, a5, 0, 0.0, -1);
	}
	else
	{
		//--
		if (gCustomBow.CheckCrossbow(CrossBow))
		{
			for (int i = 0; i < 256; i++)
			{
				if (CrossBow == GET_ITEM_MODEL(4, gCustomBow.m_CustomBow[i].ItemId))
				{
					CreateEffect(gCustomBow.m_CustomBow[i].EffectId, VecPos, WorldPos, Color, EffectType, lpModel, *(short *)(lpModel + 44), a4, a5, 0, 0.0, -1);
					//int EID[10] = { 266, 270, 272, 295, 335, 296, 297, 298, 509, 266 };
					//CreateEffect(EID[rand() % 10], VecPos, WorldPos, Color, EffectType, lpModel, *(short *)(lpModel + 44), a4, a5, 0, 0.0, -1);
				}
			}
		}
		//--
		if (gCustomBow.CheckBow(Bow))
		{
			for (int i = 0; i < 256; i++)
			{
				if (Bow == GET_ITEM_MODEL(4, gCustomBow.m_CustomBow[i].ItemId))
				{
					CreateEffect(gCustomBow.m_CustomBow[i].EffectId, VecPos, WorldPos, Color, EffectType, lpModel, *(short *)(lpModel + 44), a4, a5, 0, 0.0, -1);
				}
			}
		}
		//--
	}
}

void InitBows()
{
	for (int i = 0x0; i < 0x94A; i++)
	{
		SetByte(0x00749C90 + i, 0x90);
	}

	SetCompleteHook(0xE9, 0x00749C90, CreateBowSkillEffect);
	// ----
	for (int i = 0; i < 6; i++)
	{
		SetByte(iBowAddInventoryPos + i, 0x90);
	}

	SetCompleteHook(0xE9, iBowAddInventoryPos, cBowAddInventoryPos);
	// ----
	for (int i = 0; i < 6; i++)
	{
		SetByte(0x0056595E + i, 0x90);
	}

	SetCompleteHook(0xE9, 0x0056595E, cCrossPos);
	// ----
	for (int i = 0; i < 7; i++)
	{
		SetByte(iBowAddPlayerDimension + i, 0x90);
	}

	SetCompleteHook(0xE9, iBowAddPlayerDimension, cBowAddPlayerDimension);
	// ----
}
CustomBows.h
Código:
#pragma once
void InitBows();

#define MAX_CUSTOM_BOWS		256

#define iBowAddSkillEffect 0x74A128  //1.04E//0x00749FD8 // 1.04D ENG
#define iBowAddInventoryPos 0x005CC8E4 // 1.04E ENG
#define iBowAddPlayerDimension 0x00566178 // 1.04E ENG

#define oUserObjectStruct_ 0x8128AC4

#define sub_6D6C20 ((int(__cdecl*)(DWORD,DWORD,DWORD))0x6D6C20)
#define sub_6D9070 ((void(__cdecl*)(int,vec3_t, vec3_t , vec3_t , int , int, short , BYTE , BYTE , __int16 , float , __int16 )) 0x6D9070)

struct CUSTOM_BOWS_DATA
{
	int		Index;
	int		ItemId;
	BOOL	IsBow;
	BOOL	IsCrossbow;
	WORD	EffectId;
};

class CustomBows
{
public:
	CustomBows(){ this->Init(); };
	~CustomBows(){};

	void Init()
	{
		for (int n = 0; n < MAX_CUSTOM_BOWS; n++)
		{
			this->m_CustomBow[n].Index = -1;
		}
	};

	void Load(CUSTOM_BOWS_DATA* info);
	void SetInfo(CUSTOM_BOWS_DATA info);
	bool CheckBow(DWORD IsBowItem);
	bool CheckCrossbow(DWORD IsBowItem);

	CUSTOM_BOWS_DATA m_CustomBow[MAX_CUSTOM_BOWS];
}; extern CustomBows gCustomBow;
Exemplo da configuração do arquivo:
Código:
//------------------------------------------------------------------------------
// Desert Project Season 6 - Mu Online
// Developer: Natzugen
// skype: ----------
// Last review: 06.11.2018
//------------------------------------------------------------------------------
// Custom Bows & Crossbows config file
//------------------------------------------------------------------------------
// Valid EffecID: 266,267,268,269,270,271,272,273,274,294,
//                295,296,297,298,321,324,335,365,509
// ItemID   IsBow   IsCrossBow  EffecID
//------------------------------------------------------------------------------
// Crossbows
//------------------------------------------------------------------------------
    8       0       1           296
    8       0       1           335
    9       0       1           267
    10      0       1           271
    11      0       1           269
    12      0       1           268
    13      0       1           274
    14      0       1           273
    16      0       1           294
    18      0       1           321
    19      0       1           324
//------------------------------------------------------------------------------
// Bows
//------------------------------------------------------------------------------
    0       1       0           266
    1       1       0           266
    2       1       0           270
    3       1       0           266
    4       1       0           266
    5       1       0           266
    6       1       0           272
    17      1       0           295
    20      1       0           335
    21      1       0           296
    22      1       0           297
    23      1       0           298
    24      1       0           509
    27      1       0           266
end
Creditos:
Nemesis
MyHeart
Natzugen