Não tenho nenhum deste Bug's aqui. Use o cliente deste Servidor https://iconemu.com/#void .
Printable View
Não tenho nenhum deste Bug's aqui. Use o cliente deste Servidor https://iconemu.com/#void .Citação:
Muito bom @André thumbup
Não suma do fórum não cool
tanks now work perfectCitação:
any cant help me,how to see struc (gaps) in ida pro? or how configue it for see it?
Assista este vídeo Tutorial, será mais fácil para você pois explicar por texto é complicado:Citação:
https://www.youtube.com/watch?v=3fDOk8Q9Fq0
It does not explain how to create, see that to create that part :( I need to see what it shows at minute 12:39 in ida proCitação:
Assista este vídeo Tutorial, será mais fácil para você pois explicar por texto é complicado:
https://www.youtube.com/watch?v=3fDOk8Q9Fq0
Citação:
Como estou sem tempo para finalizar um Repack com correções devido ao meu retorno ao trabalho :(, irei recolocar os Fixes novamente neste tópico.
SEMPRE LEIAM TODAS AS PÁGINAS PARA ENCONTRAR POSSÍVEIS FIXES E CUIDADO COM "VENDEDORES PICARETAS" QUE SÓ QUEREM SE APROVEITAR!
Fix Dark Reaven (Corvo) não causar dano:
Em DarkSpirit.cpp no GS
Busque por:
Substitua tudo por:Código:bool CDarkSpirit::Attack(LPOBJ lpObj, LPOBJ lpTarget, CSkill* lpSkill, bool send, BYTE flag, BYTE action) // OK
Fix NPC em Lorencia não aceitar itens de combinação para Criar Dark Reaven (Corvo) e Dark Horse (Cavalo) e também a Chaos Machine:Código:bool CDarkSpirit::Attack(LPOBJ lpObj,LPOBJ lpTarget,CSkill* lpSkill,bool send,BYTE flag,BYTE action) // OK{
#pragma region ATTACK_CHECK
if(lpObj->Index == lpTarget->Index)
{
return 0;
}
if(lpObj->Type == OBJECT_USER && gObjIsConnectedGP(lpObj->Index) == 0)
{
return 0;
}
if(lpTarget->Type == OBJECT_USER && gObjIsConnectedGP(lpTarget->Index) == 0)
{
return 0;
}
if(gMap[lpObj->Map].CheckAttr(lpObj->X,lpObj->Y,1) != 0 || gMap[lpTarget->Map].CheckAttr(lpTarget->X,lpTarget->Y,1) != 0)
{
return 0;
}
#if(GAMESERVER_UPDATE>=402)
if(gDuel.GetDuelArenaBySpectator(lpObj->Index) != 0 || gDuel.GetDuelArenaBySpectator(lpTarget->Index) != 0)
{
return 0;
}
#endif
if(gCrywolf.GetCrywolfState() == CRYWOLF_STATE_READY || gCrywolf.GetCrywolfState() == CRYWOLF_STATE_END)
{
if(lpTarget->Type == OBJECT_MONSTER && lpTarget->Map == MAP_CRYWOLF)
{
return 0;
}
}
if(lpObj->GuildNumber > 0 && lpObj->Guild != 0 && lpObj->Guild->WarState != 0)
{
if(lpObj->Guild->WarType == 1 && GetBattleSoccerGoalMove(0) == 0)
{
return 1;
}
if(lpObj->Guild->WarType == 0 && lpTarget->Type == OBJECT_MONSTER)
{
return 0;
}
}
if(lpTarget->Type == OBJECT_NPC || lpTarget->Live == 0 || lpTarget->State != OBJECT_PLAYING || lpTarget->Teleport != 0)
{
return 0;
}
if(lpTarget->Type == OBJECT_MONSTER)
{
if((lpTarget->Class >= 100 && lpTarget->Class <= 110) || lpTarget->Class == 523) // Trap
{
return 0;
}
if(lpTarget->Class == 221 || lpTarget->Class == 222) // Siege
{
return 0;
}
}
if(lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_MONSTER)
{
if(OBJECT_RANGE(lpObj->SummonIndex) != 0)
{
if(lpObj->SummonIndex == lpTarget->Index)
{
return 0;
}
}
}
int SummonIndex = lpObj->Index;
if(lpObj->Type == OBJECT_MONSTER && OBJECT_RANGE(lpObj->SummonIndex) != 0)
{
SummonIndex = lpObj->SummonIndex;
}
int SummonTargetIndex = lpTarget->Index;
if(lpTarget->Type == OBJECT_MONSTER && OBJECT_RANGE(lpTarget->SummonIndex) != 0)
{
SummonTargetIndex = lpTarget->SummonIndex;
}
if(gAttack.CheckPlayerTarget(&gObj[SummonIndex],&gObj[SummonTargetIndex]) == 0)
{
return 0;
}
#pragma endregion
#pragma region ATTACK_RETURN
int skill = ((lpSkill==0)?SKILL_NONE:lpSkill->m_skill);
if(lpObj->Type == OBJECT_USER)
{
lpObj->HPAutoRecuperationTime = GetTickCount();
lpObj->MPAutoRecuperationTime = GetTickCount();
lpObj->BPAutoRecuperationTime = GetTickCount();
lpObj->SDAutoRecuperationTime = GetTickCount();
}
if(lpTarget->Type == OBJECT_USER)
{
lpTarget->HPAutoRecuperationTime = GetTickCount();
lpTarget->MPAutoRecuperationTime = GetTickCount();
lpTarget->BPAutoRecuperationTime = GetTickCount();
lpTarget->SDAutoRecuperationTime = GetTickCount();
}
if(OBJECT_RANGE(lpObj->SummonIndex) != 0)
{
gObjSummonSetEnemy(lpObj,lpTarget->Index);
}
if(lpObj->Type == OBJECT_USER)
{
gDarkSpirit[lpObj->Index].SetTarget(lpTarget->Index);
}
bool duel = gDuel.CheckDuel(lpObj,lpTarget);
if(lpObj->Type == OBJECT_USER && duel != 0)
{
lpObj->DuelTickCount = GetTickCount();
}
if(lpTarget->Type == OBJECT_USER && duel != 0)
{
lpTarget->DuelTickCount = GetTickCount();
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_ORDER_OF_PROTECTION) != 0 && lpSkill == 0)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_ORDER_OF_PROTECTION) != 0 && lpSkill != 0)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_PHYSI_DAMAGE_IMMUNITY) != 0 && lpSkill == 0)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_MAGIC_DAMAGE_IMMUNITY) != 0 && lpSkill != 0)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(lpTarget->Type == OBJECT_MONSTER)
{
if(lpTarget->Class == 200 && lpSkill == 0)
{
gObjMonsterStateProc(lpTarget,6,lpObj->Index,0);
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(lpTarget->Class == 200 && lpSkill != 0)
{
gObjMonsterStateProc(lpTarget,7,lpObj->Index,0);
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_MONSTER_PHYSI_DAMAGE_IMMUNITY) != 0 && skill == SKILL_NONE)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_MONSTER_MAGIC_DAMAGE_IMMUNITY) != 0 && skill != SKILL_NONE)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(lpTarget->MonsterSkillElementOption.CheckImmuneTime() != 0)
{
if(lpTarget->MonsterSkillElementOption.m_SkillElementImmuneNumber == skill)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
}
}
#pragma endregion
#pragma region DAMAGE_CALC
flag = 0;
BYTE miss = 0;
WORD effect = 0;
if((lpObj->Type != OBJECT_USER || lpTarget->Type != OBJECT_USER) && this->MissCheck(lpObj,lpTarget,lpSkill,send,&miss) == 0)
{
return 1;
}
if((lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_USER) && gAttack.MissCheckPvP(lpObj,lpTarget,lpSkill,send,0,&miss) == 0)
{
return 1;
}
long long defense = this->GetTargetDefense(lpObj,lpTarget,&effect);
long long damage = this->GetAttackDamage(lpObj,lpTarget,lpSkill,&effect,defense);
if(miss != 0)
{
damage = (damage*30)/100;
}
if(action != 0)
{
damage = (damage*60)/100;
}
for(int n=0;n < MAX_DAMAGE_REDUCTION;n++)
{
damage -= (damage*lpTarget->DamageReduction[n])/100;
}
if(lpTarget->EffectOption.AddDamageReduction > 0)
{
damage -= (damage*lpTarget->EffectOption.AddDamageReduction)/100;
}
if((GetTickCount()-lpTarget->ShieldDamageReductionTime) < ((DWORD)(gServerInfo.m_DefenseTimeConstA*1000)))
{
damage -= (damage*lpTarget->ShieldDamageReduction)/100;
}
gAttack.WingSprite(0,lpTarget,&damage);
gAttack.HelperSprite(0,lpTarget,&damage);
int MinDamage = (lpObj->Level+lpObj->MasterLevel)/10;
MinDamage = ((MinDamage<1)?1:MinDamage);
damage = ((damage<MinDamage)?MinDamage:damage);
this->DarkSpiritSprite(lpObj,damage);
gAttack.DamageSprite(lpTarget,damage);
#if(GAMESERVER_UPDATE>=602)
if((GetLargeRand()%100) < gMasterSkillTree.GetMasterSkillValue(lpObj,MASTER_SKILL_ADD_DARK_SPIRIT_DOUBLE_DAMAGE_RATE))
{
effect |= 0x40;
damage += damage;
}
#endif
#pragma endregion
#pragma region DAMAGE_CONFIG
if(lpObj->Type == OBJECT_USER)
{
if(lpTarget->Type == OBJECT_USER)
{
damage = (damage*gServerInfo.m_GeneralDamageRatePvP)/100;
damage = (damage*gServerInfo.m_DamageRatePvP[lpObj->Class])/100;
damage = (damage*gServerInfo.m_DamageRateTo[lpObj->Class][lpTarget->Class])/100;
if(duel != 0)
{
damage = (damage*gServerInfo.m_DuelDamageRate)/100;
}
else if(gGensSystem.CheckGens(lpObj,lpTarget) != 0)
{
damage = (damage*gServerInfo.m_GensDamageRate)/100;
}
else if(CC_MAP_RANGE(lpObj->Map) != 0 && CC_MAP_RANGE(lpTarget->Map) != 0)
{
damage = (damage*gServerInfo.m_ChaosCastleDamageRate)/100;
}
else if(IT_MAP_RANGE(lpObj->Map) != 0 && IT_MAP_RANGE(lpTarget->Map) != 0)
{
damage = (damage*gServerInfo.m_IllusionTempleDamageRate)/100;
}
}
else
{
damage = (damage*gServerInfo.m_GeneralDamageRatePvM)/100;
damage = (damage*gServerInfo.m_DamageRatePvM[lpObj->Class])/100;
}
}
#pragma endregion
#pragma region DAMAGE_FINISH
if(lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_MONSTER)
{
}
damage = ((damage<0)?0:damage);
#pragma endregion
#pragma region DAMAGE_APPLY
int ShieldDamage = 0;
if(lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_USER)
{
ShieldDamage = gAttack.GetShieldDamage(lpObj,lpTarget,damage);
if(lpTarget->Life < (damage-ShieldDamage))
{
lpTarget->Life = 0;
}
else
{
lpTarget->Life -= damage-ShieldDamage;
}
if(lpTarget->Shield < ShieldDamage)
{
lpTarget->Shield = 0;
}
else
{
lpTarget->Shield -= ShieldDamage;
}
}
else
{
if(lpTarget->Life < damage)
{
lpTarget->Life = 0;
}
else
{
lpTarget->Life -= damage;
}
}
if(lpTarget->Type == OBJECT_MONSTER)
{
lpTarget->LastAttackerID = lpObj->Index;
gObjAddMsgSendDelay(lpTarget,0,lpObj->Index,100,0);
if(lpTarget->CurrentAI != 0)
{
lpTarget->Agro.IncAgro(lpObj->Index,(damage/50));
}
}
#pragma endregion
#pragma region CHECK_SELF_DEFENSE
if(damage > 0)
{
if(lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_USER && lpObj->Index != lpTarget->Index)
{
bool CheckSelfDefense = 1;
if(effect == 4)
{
CheckSelfDefense = 0;
}
if(gDuel.CheckDuel(lpObj,lpTarget) != 0)
{
CheckSelfDefense = 0;
}
if(gGensSystem.CheckGens(lpObj,lpTarget) != 0)
{
CheckSelfDefense = 0;
}
if(CC_MAP_RANGE(lpObj->Map) != 0 && CC_MAP_RANGE(lpTarget->Map) != 0)
{
CheckSelfDefense = 0;
}
if(IT_MAP_RANGE(lpObj->Map) != 0 && IT_MAP_RANGE(lpTarget->Map) != 0)
{
CheckSelfDefense = 0;
}
if(gMapManager.GetMapNonOutlaw(lpObj->Map) != 0)
{
CheckSelfDefense = 0;
}
if(CheckSelfDefense != 0)
{
gObjCheckSelfDefense(lpObj,lpTarget->Index);
}
}
gAttack.ArmorDurabilityDown(lpObj,lpTarget);
}
lpObj->Rest = 0;
#pragma endregion
#pragma region ATTACK_FINISH
if(damage > 0)
{
gEffectManager.DelEffect(lpTarget,EFFECT_SLEEP);
if(lpTarget->Type == OBJECT_USER)
{
if(effect != 4)
{
if((lpTarget->DamageReflect+lpTarget->EffectOption.AddDamageReflect) > 0)
{
gObjAddMsgSendDelay(lpTarget,10,lpObj->Index,10,((damage*(lpTarget->DamageReflect+lpTarget->EffectOption.AddDamageReflect))/100));
}
if((GetLargeRand()%100) < lpTarget->DefensiveFullBPRestoreRate)
{
lpTarget->BP = lpTarget->MaxBP+lpTarget->AddBP;
GCManaSend(lpTarget->Index,0xFF,(int)lpTarget->Mana,lpTarget->BP);
}
}
int effect = 1;
}
gObjectManager.CharacterLifeCheck(lpObj,lpTarget,(damage-ShieldDamage),0,flag,effect,skill,ShieldDamage/*,0*/);
}
else
{
GCDamageSend(lpObj->Index,lpTarget->Index,0,0,effect,0);
}
if(lpObj->Type == OBJECT_USER && lpObj->Life <= 0 && lpObj->CheckLifeTime <= 0)
{
lpObj->AttackObj = lpTarget;
lpObj->AttackerKilled = ((lpTarget->Type==OBJECT_USER)?1:0);
lpObj->CheckLifeTime = 3;
}
#pragma endregion
return 1;
}
Em Main.cpp do Cliente:
Busque por:
Apenas coloque // para comentar e desativar esta linha.Código:SetCompleteHook(0xE9, 0x583799, &ChaosBoxDurationItens);
Fix Arquivos de Configurações não aplicarem os efeitos no GS:
Alguns arquivos do GameServer estão com falta do end em seus respectivos finais ou colunas, verifique na Source buscando pelos trechos onde
estão programadas as leituras destes arquivos que não possuem o end e confirme a necessidade dele. Na programação do GameServer não está
incluído um alerta para a má leitura dos arquivos decorrente da falta de caracteres ou má colocação deles, desta forma, o GS inicia como se estivesse tudo bem porém não aplica as configurações do arquivo com erro.
Exemplo de arquivo com erro que necessita colocação do end:
SkillBlock.txt na pasta Data/Skill do MuServer.
Master Skill Tree 4:
Como esta Source não é de fato uma Season 13, mas sim um Upgrade de Season, está faltando a finalização da Master Skill Tree 4 e suas respectivas Skills. Eu não tenho como disponibilizar o código pois eu apenas fui montando o sistema durante vários dias e isso envolveu diversos arquivos e linhas de códigos. A dica que dou é que todo o sistema da Tree 4 fica basicamente nos arquivos SkillManager, MasterSkillTree_4th, Attack e Skill da Source do GS.
Ao contrário do que falaram algumas páginas atrás neste tópico, NÃO COPIE E COLE ARQUIVOS DE OUTRAS TEAMS como MuDev e etc..., nenhum destes arquivos, como o FormulaData.txt, é compatível com esta Source e conforme informei logo acima, o GS não acusa o arquivo incorreto na leitura e ao usar este arquivo de outra Team que eu citei, a única coisa que irá acontecer é a Tree 4 bugar não informando os valores corretos adquiridos por cada ponto adicionado e também não atualizar os respectivos valores. Use os arquivos originais do MuServer pois eles estão OK para a Master Skill Tree 4, sendo necessária mudanças apenas se você quiser modificar a quantidade de pontos necessários e etc...
Para ativar esta Master Skill Tree 4, apenas busque por:
Código:return; //disabled until full implementation and test of skills
Coloque // na frente do return;
Não é necessário fazer absolutamente mais nada na Source para que esta Tree funcione.
Logo após ative no arquivo GameServerInfo - Common.dat no GS deixando assim ForMasterSkillTree = 1.
Fix não Salvar Skills da Master Skill Tree 4:
Em MasterSkillTree_4th.cpp do GS busque por:Código:case FOR_MASTER_SKILL_ADD_SHOCKING_BOOM : if ((value = gSkillManager.AddSkill(lpObj, SKILL_SHOCKING_BOOM, 0)) >= 0)
{
gSkillManager.GCSkillAddSend(lpObj->Index, value, SKILL_SHOCKING_BOOM, 0, 0);
}
break;
Esta será a sua referência.
Repare que as outras Skills da Tree 4 não possuem nada disso e agora cabe a você fazer de cada uma tendo atenção nos respectivos nomes das Skills.
OBS: Como eu falei, as mudanças e correções que eu tive que realizar foram muitas em diversos arquivos, mas pelo o que me recordo, o Fix para este caso é apenas este.
Não edite as Skills dos personagens no Banco de Dados, para testes crie um personagem para testar cada Skill. No Banco de Dados a inserção ocorre em diversos locais e editar irá bugar o char fazendo com que você se atrapalhe ainda mais.
Algumas imagens das Skills em funcionamento:
Shock
https://i.imgur.com/2sF7dz8.png
Bleeding
https://i.imgur.com/V1cZcDM.png
Poison
https://i.imgur.com/AM3D8lf.png
---Por enquanto é isso. Espero que ajude alguém a desenvolver o seu projeto e infelizmente não tenho previsão de retornar o desenvolvimento devido ao fim do recesso no trabalho. Sempre que eu puder irei auxiliar quem precisar de ajuda.
Hello. Thank you very much for your fix, brother. But I have a question, how to make the DLL support Chinese? After I translated the original English into Chinese and compiled it, the client will have garbled characters
Atualizando Post com Fixes...Citação:
Como estou sem tempo para finalizar um Repack com correções devido ao meu retorno ao trabalho :(, irei recolocar os Fixes novamente neste tópico.
SEMPRE LEIAM TODAS AS PÁGINAS PARA ENCONTRAR POSSÍVEIS FIXES E CUIDADO COM "VENDEDORES PICARETAS" QUE SÓ QUEREM SE APROVEITAR!
Fix Dark Reaven (Corvo) não causar dano:
Em DarkSpirit.cpp no GS
Busque por:
Substitua tudo por:Código:bool CDarkSpirit::Attack(LPOBJ lpObj, LPOBJ lpTarget, CSkill* lpSkill, bool send, BYTE flag, BYTE action) // OK
Fix NPC em Lorencia não aceitar itens de combinação para Criar Dark Reaven (Corvo) e Dark Horse (Cavalo) e também a Chaos Machine:Código:bool CDarkSpirit::Attack(LPOBJ lpObj,LPOBJ lpTarget,CSkill* lpSkill,bool send,BYTE flag,BYTE action) // OK{
#pragma region ATTACK_CHECK
if(lpObj->Index == lpTarget->Index)
{
return 0;
}
if(lpObj->Type == OBJECT_USER && gObjIsConnectedGP(lpObj->Index) == 0)
{
return 0;
}
if(lpTarget->Type == OBJECT_USER && gObjIsConnectedGP(lpTarget->Index) == 0)
{
return 0;
}
if(gMap[lpObj->Map].CheckAttr(lpObj->X,lpObj->Y,1) != 0 || gMap[lpTarget->Map].CheckAttr(lpTarget->X,lpTarget->Y,1) != 0)
{
return 0;
}
#if(GAMESERVER_UPDATE>=402)
if(gDuel.GetDuelArenaBySpectator(lpObj->Index) != 0 || gDuel.GetDuelArenaBySpectator(lpTarget->Index) != 0)
{
return 0;
}
#endif
if(gCrywolf.GetCrywolfState() == CRYWOLF_STATE_READY || gCrywolf.GetCrywolfState() == CRYWOLF_STATE_END)
{
if(lpTarget->Type == OBJECT_MONSTER && lpTarget->Map == MAP_CRYWOLF)
{
return 0;
}
}
if(lpObj->GuildNumber > 0 && lpObj->Guild != 0 && lpObj->Guild->WarState != 0)
{
if(lpObj->Guild->WarType == 1 && GetBattleSoccerGoalMove(0) == 0)
{
return 1;
}
if(lpObj->Guild->WarType == 0 && lpTarget->Type == OBJECT_MONSTER)
{
return 0;
}
}
if(lpTarget->Type == OBJECT_NPC || lpTarget->Live == 0 || lpTarget->State != OBJECT_PLAYING || lpTarget->Teleport != 0)
{
return 0;
}
if(lpTarget->Type == OBJECT_MONSTER)
{
if((lpTarget->Class >= 100 && lpTarget->Class <= 110) || lpTarget->Class == 523) // Trap
{
return 0;
}
if(lpTarget->Class == 221 || lpTarget->Class == 222) // Siege
{
return 0;
}
}
if(lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_MONSTER)
{
if(OBJECT_RANGE(lpObj->SummonIndex) != 0)
{
if(lpObj->SummonIndex == lpTarget->Index)
{
return 0;
}
}
}
int SummonIndex = lpObj->Index;
if(lpObj->Type == OBJECT_MONSTER && OBJECT_RANGE(lpObj->SummonIndex) != 0)
{
SummonIndex = lpObj->SummonIndex;
}
int SummonTargetIndex = lpTarget->Index;
if(lpTarget->Type == OBJECT_MONSTER && OBJECT_RANGE(lpTarget->SummonIndex) != 0)
{
SummonTargetIndex = lpTarget->SummonIndex;
}
if(gAttack.CheckPlayerTarget(&gObj[SummonIndex],&gObj[SummonTargetIndex]) == 0)
{
return 0;
}
#pragma endregion
#pragma region ATTACK_RETURN
int skill = ((lpSkill==0)?SKILL_NONE:lpSkill->m_skill);
if(lpObj->Type == OBJECT_USER)
{
lpObj->HPAutoRecuperationTime = GetTickCount();
lpObj->MPAutoRecuperationTime = GetTickCount();
lpObj->BPAutoRecuperationTime = GetTickCount();
lpObj->SDAutoRecuperationTime = GetTickCount();
}
if(lpTarget->Type == OBJECT_USER)
{
lpTarget->HPAutoRecuperationTime = GetTickCount();
lpTarget->MPAutoRecuperationTime = GetTickCount();
lpTarget->BPAutoRecuperationTime = GetTickCount();
lpTarget->SDAutoRecuperationTime = GetTickCount();
}
if(OBJECT_RANGE(lpObj->SummonIndex) != 0)
{
gObjSummonSetEnemy(lpObj,lpTarget->Index);
}
if(lpObj->Type == OBJECT_USER)
{
gDarkSpirit[lpObj->Index].SetTarget(lpTarget->Index);
}
bool duel = gDuel.CheckDuel(lpObj,lpTarget);
if(lpObj->Type == OBJECT_USER && duel != 0)
{
lpObj->DuelTickCount = GetTickCount();
}
if(lpTarget->Type == OBJECT_USER && duel != 0)
{
lpTarget->DuelTickCount = GetTickCount();
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_ORDER_OF_PROTECTION) != 0 && lpSkill == 0)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_ORDER_OF_PROTECTION) != 0 && lpSkill != 0)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_PHYSI_DAMAGE_IMMUNITY) != 0 && lpSkill == 0)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_MAGIC_DAMAGE_IMMUNITY) != 0 && lpSkill != 0)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(lpTarget->Type == OBJECT_MONSTER)
{
if(lpTarget->Class == 200 && lpSkill == 0)
{
gObjMonsterStateProc(lpTarget,6,lpObj->Index,0);
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(lpTarget->Class == 200 && lpSkill != 0)
{
gObjMonsterStateProc(lpTarget,7,lpObj->Index,0);
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_MONSTER_PHYSI_DAMAGE_IMMUNITY) != 0 && skill == SKILL_NONE)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_MONSTER_MAGIC_DAMAGE_IMMUNITY) != 0 && skill != SKILL_NONE)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(lpTarget->MonsterSkillElementOption.CheckImmuneTime() != 0)
{
if(lpTarget->MonsterSkillElementOption.m_SkillElementImmuneNumber == skill)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
}
}
#pragma endregion
#pragma region DAMAGE_CALC
flag = 0;
BYTE miss = 0;
WORD effect = 0;
if((lpObj->Type != OBJECT_USER || lpTarget->Type != OBJECT_USER) && this->MissCheck(lpObj,lpTarget,lpSkill,send,&miss) == 0)
{
return 1;
}
if((lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_USER) && gAttack.MissCheckPvP(lpObj,lpTarget,lpSkill,send,0,&miss) == 0)
{
return 1;
}
long long defense = this->GetTargetDefense(lpObj,lpTarget,&effect);
long long damage = this->GetAttackDamage(lpObj,lpTarget,lpSkill,&effect,defense);
if(miss != 0)
{
damage = (damage*30)/100;
}
if(action != 0)
{
damage = (damage*60)/100;
}
for(int n=0;n < MAX_DAMAGE_REDUCTION;n++)
{
damage -= (damage*lpTarget->DamageReduction[n])/100;
}
if(lpTarget->EffectOption.AddDamageReduction > 0)
{
damage -= (damage*lpTarget->EffectOption.AddDamageReduction)/100;
}
if((GetTickCount()-lpTarget->ShieldDamageReductionTime) < ((DWORD)(gServerInfo.m_DefenseTimeConstA*1000)))
{
damage -= (damage*lpTarget->ShieldDamageReduction)/100;
}
gAttack.WingSprite(0,lpTarget,&damage);
gAttack.HelperSprite(0,lpTarget,&damage);
int MinDamage = (lpObj->Level+lpObj->MasterLevel)/10;
MinDamage = ((MinDamage<1)?1:MinDamage);
damage = ((damage<MinDamage)?MinDamage:damage);
this->DarkSpiritSprite(lpObj,damage);
gAttack.DamageSprite(lpTarget,damage);
#if(GAMESERVER_UPDATE>=602)
if((GetLargeRand()%100) < gMasterSkillTree.GetMasterSkillValue(lpObj,MASTER_SKILL_ADD_DARK_SPIRIT_DOUBLE_DAMAGE_RATE))
{
effect |= 0x40;
damage += damage;
}
#endif
#pragma endregion
#pragma region DAMAGE_CONFIG
if(lpObj->Type == OBJECT_USER)
{
if(lpTarget->Type == OBJECT_USER)
{
damage = (damage*gServerInfo.m_GeneralDamageRatePvP)/100;
damage = (damage*gServerInfo.m_DamageRatePvP[lpObj->Class])/100;
damage = (damage*gServerInfo.m_DamageRateTo[lpObj->Class][lpTarget->Class])/100;
if(duel != 0)
{
damage = (damage*gServerInfo.m_DuelDamageRate)/100;
}
else if(gGensSystem.CheckGens(lpObj,lpTarget) != 0)
{
damage = (damage*gServerInfo.m_GensDamageRate)/100;
}
else if(CC_MAP_RANGE(lpObj->Map) != 0 && CC_MAP_RANGE(lpTarget->Map) != 0)
{
damage = (damage*gServerInfo.m_ChaosCastleDamageRate)/100;
}
else if(IT_MAP_RANGE(lpObj->Map) != 0 && IT_MAP_RANGE(lpTarget->Map) != 0)
{
damage = (damage*gServerInfo.m_IllusionTempleDamageRate)/100;
}
}
else
{
damage = (damage*gServerInfo.m_GeneralDamageRatePvM)/100;
damage = (damage*gServerInfo.m_DamageRatePvM[lpObj->Class])/100;
}
}
#pragma endregion
#pragma region DAMAGE_FINISH
if(lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_MONSTER)
{
}
damage = ((damage<0)?0:damage);
#pragma endregion
#pragma region DAMAGE_APPLY
int ShieldDamage = 0;
if(lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_USER)
{
ShieldDamage = gAttack.GetShieldDamage(lpObj,lpTarget,damage);
if(lpTarget->Life < (damage-ShieldDamage))
{
lpTarget->Life = 0;
}
else
{
lpTarget->Life -= damage-ShieldDamage;
}
if(lpTarget->Shield < ShieldDamage)
{
lpTarget->Shield = 0;
}
else
{
lpTarget->Shield -= ShieldDamage;
}
}
else
{
if(lpTarget->Life < damage)
{
lpTarget->Life = 0;
}
else
{
lpTarget->Life -= damage;
}
}
if(lpTarget->Type == OBJECT_MONSTER)
{
lpTarget->LastAttackerID = lpObj->Index;
gObjAddMsgSendDelay(lpTarget,0,lpObj->Index,100,0);
if(lpTarget->CurrentAI != 0)
{
lpTarget->Agro.IncAgro(lpObj->Index,(damage/50));
}
}
#pragma endregion
#pragma region CHECK_SELF_DEFENSE
if(damage > 0)
{
if(lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_USER && lpObj->Index != lpTarget->Index)
{
bool CheckSelfDefense = 1;
if(effect == 4)
{
CheckSelfDefense = 0;
}
if(gDuel.CheckDuel(lpObj,lpTarget) != 0)
{
CheckSelfDefense = 0;
}
if(gGensSystem.CheckGens(lpObj,lpTarget) != 0)
{
CheckSelfDefense = 0;
}
if(CC_MAP_RANGE(lpObj->Map) != 0 && CC_MAP_RANGE(lpTarget->Map) != 0)
{
CheckSelfDefense = 0;
}
if(IT_MAP_RANGE(lpObj->Map) != 0 && IT_MAP_RANGE(lpTarget->Map) != 0)
{
CheckSelfDefense = 0;
}
if(gMapManager.GetMapNonOutlaw(lpObj->Map) != 0)
{
CheckSelfDefense = 0;
}
if(CheckSelfDefense != 0)
{
gObjCheckSelfDefense(lpObj,lpTarget->Index);
}
}
gAttack.ArmorDurabilityDown(lpObj,lpTarget);
}
lpObj->Rest = 0;
#pragma endregion
#pragma region ATTACK_FINISH
if(damage > 0)
{
gEffectManager.DelEffect(lpTarget,EFFECT_SLEEP);
if(lpTarget->Type == OBJECT_USER)
{
if(effect != 4)
{
if((lpTarget->DamageReflect+lpTarget->EffectOption.AddDamageReflect) > 0)
{
gObjAddMsgSendDelay(lpTarget,10,lpObj->Index,10,((damage*(lpTarget->DamageReflect+lpTarget->EffectOption.AddDamageReflect))/100));
}
if((GetLargeRand()%100) < lpTarget->DefensiveFullBPRestoreRate)
{
lpTarget->BP = lpTarget->MaxBP+lpTarget->AddBP;
GCManaSend(lpTarget->Index,0xFF,(int)lpTarget->Mana,lpTarget->BP);
}
}
int effect = 1;
}
gObjectManager.CharacterLifeCheck(lpObj,lpTarget,(damage-ShieldDamage),0,flag,effect,skill,ShieldDamage/*,0*/);
}
else
{
GCDamageSend(lpObj->Index,lpTarget->Index,0,0,effect,0);
}
if(lpObj->Type == OBJECT_USER && lpObj->Life <= 0 && lpObj->CheckLifeTime <= 0)
{
lpObj->AttackObj = lpTarget;
lpObj->AttackerKilled = ((lpTarget->Type==OBJECT_USER)?1:0);
lpObj->CheckLifeTime = 3;
}
#pragma endregion
return 1;
}
Em Main.cpp do Cliente:
Busque por:
Apenas coloque // para comentar e desativar esta linha.Código:SetCompleteHook(0xE9, 0x583799, &ChaosBoxDurationItens);
Fix Arquivos de Configurações não aplicarem os efeitos no GS:
Alguns arquivos do GameServer estão com falta do end em seus respectivos finais ou colunas, verifique na Source buscando pelos trechos onde
estão programadas as leituras destes arquivos que não possuem o end e confirme a necessidade dele. Na programação do GameServer não está
incluído um alerta para a má leitura dos arquivos decorrente da falta de caracteres ou má colocação deles, desta forma, o GS inicia como se estivesse tudo bem porém não aplica as configurações do arquivo com erro.
Exemplo de arquivo com erro que necessita colocação do end:
SkillBlock.txt na pasta Data/Skill do MuServer.
Master Skill Tree 4:
Como esta Source não é de fato uma Season 13, mas sim um Upgrade de Season, está faltando a finalização da Master Skill Tree 4 e suas respectivas Skills. Eu não tenho como disponibilizar o código pois eu apenas fui montando o sistema durante vários dias e isso envolveu diversos arquivos e linhas de códigos. A dica que dou é que todo o sistema da Tree 4 fica basicamente nos arquivos SkillManager, MasterSkillTree_4th, Attack e Skill da Source do GS.
Ao contrário do que falaram algumas páginas atrás neste tópico, NÃO COPIE E COLE ARQUIVOS DE OUTRAS TEAMS como MuDev e etc..., nenhum destes arquivos, como o FormulaData.txt, é compatível com esta Source e conforme informei logo acima, o GS não acusa o arquivo incorreto na leitura e ao usar este arquivo de outra Team que eu citei, a única coisa que irá acontecer é a Tree 4 bugar não informando os valores corretos adquiridos por cada ponto adicionado e também não atualizar os respectivos valores. Use os arquivos originais do MuServer pois eles estão OK para a Master Skill Tree 4, sendo necessária mudanças apenas se você quiser modificar a quantidade de pontos necessários e etc...
Para ativar esta Master Skill Tree 4, apenas busque por:
Código:return; //disabled until full implementation and test of skills
Coloque // na frente do return;
Não é necessário fazer absolutamente mais nada na Source para que esta Tree funcione.
Logo após ative no arquivo GameServerInfo - Common.dat no GS deixando assim ForMasterSkillTree = 1.
Fix não Salvar Skills da Master Skill Tree 4:
Em MasterSkillTree_4th.cpp do GS busque por:Código:case FOR_MASTER_SKILL_ADD_SHOCKING_BOOM : if ((value = gSkillManager.AddSkill(lpObj, SKILL_SHOCKING_BOOM, 0)) >= 0)
{
gSkillManager.GCSkillAddSend(lpObj->Index, value, SKILL_SHOCKING_BOOM, 0, 0);
}
break;
Esta será a sua referência.
Repare que as outras Skills da Tree 4 não possuem nada disso e agora cabe a você fazer de cada uma tendo atenção nos respectivos nomes das Skills.
OBS: Como eu falei, as mudanças e correções que eu tive que realizar foram muitas em diversos arquivos, mas pelo o que me recordo, o Fix para este caso é apenas este.
Não edite as Skills dos personagens no Banco de Dados, para testes crie um personagem para testar cada Skill. No Banco de Dados a inserção ocorre em diversos locais e editar irá bugar o char fazendo com que você se atrapalhe ainda mais.
Algumas imagens das Skills em funcionamento:
Shock
https://i.imgur.com/2sF7dz8.png
Bleeding
https://i.imgur.com/V1cZcDM.png
Poison
https://i.imgur.com/AM3D8lf.png
---Por enquanto é isso. Espero que ajude alguém a desenvolver o seu projeto e infelizmente não tenho previsão de retornar o desenvolvimento devido ao fim do recesso no trabalho. Sempre que eu puder irei auxiliar quem precisar de ajuda.
Este MS está programado com limite de 50.000 WCoinC e caso adicione mais que isso todo o sistema de compra por Moedas e Saldos bugam!
Para alterar ou remover o Limite de WCoinC:
Em CashShop.cpp do GS busque por:
Altere o valor de 500000 para o desejado.Código:if (lpMsg->WCoinC < 0 || lpMsg->WCoinC > 50000){
lpMsg->WCoinC = 0;
}
Andre Excelente contribuição André, você tem alguma ideia sobre os offsets das câmeras 3D? E onde está discutido o recurso para que você só possa ativar os efeitos de buff, como o escudo de mana interno, hein, sozinho no cerco do castelo?
any cant create MakePreviewCharSet for customwing plis this is the offset SetCompleteHook(0xE8, 0x0061404E, &sub_621038);
Você poderia compartilhar os deslocamentos da câmera 3D, se os tiver?