void QuitarPet(int UserIndex, int NpcIndex) { /* '*************************************************** */ /* 'Autor: ZaMa */ /* 'Last Modification: 18/11/2009 */ /* 'Kills a pet */ /* '*************************************************** */ int i; int PetIndex = 0; /* ' Busco el indice de la mascota */ for (i = (1); i <= (MAXMASCOTAS); i++) { if (UserList[UserIndex].MascotasIndex[i] == NpcIndex) { PetIndex = i; } } /* ' Poco probable que pase, pero por las dudas.. */ if (PetIndex == 0) { return; } /* ' Limpio el slot de la mascota */ UserList[UserIndex].NroMascotas = UserList[UserIndex].NroMascotas - 1; UserList[UserIndex].MascotasIndex[PetIndex] = 0; UserList[UserIndex].MascotasType[PetIndex] = 0; /* ' Elimino la mascota */ QuitarNPC(NpcIndex); }
void CentinelaUserLogout(int CentinelaIndex) { /* '************************************************* */ /* 'Author: Unknown */ /* 'Last modified: 02/11/2010 */ /* 'El usuario al que revisabamos se desconectó */ /* '02/10/2010: ZaMa - Adaptado para que funcione mas de un centinela en paralelo. */ /* '02/11/2010: ZaMa - Ahora no loguea que el usuario cerro si puso bien la clave. */ /* '************************************************* */ if (Centinela[CentinelaIndex].RevisandoUserIndex != 0) { /* 'Logueamos el evento */ if (!UserList[Centinela[CentinelaIndex].RevisandoUserIndex].flags.CentinelaOK) { LogCentinela( "El usuario " + UserList[Centinela[CentinelaIndex].RevisandoUserIndex].Name + " se desolgueó al pedirsele la contrasena."); } /* 'Reseteamos y esperamos a otro PasarMinuto para ir al siguiente user */ Centinela[CentinelaIndex].clave = 0; Centinela[CentinelaIndex].TiempoRestante = 0; Centinela[CentinelaIndex].RevisandoUserIndex = 0; Centinela[CentinelaIndex].Activo = false; if (Centinela[CentinelaIndex].NpcIndex != 0) { QuitarNPC(Centinela[CentinelaIndex].NpcIndex); Centinela[CentinelaIndex].NpcIndex = 0; } } }
void CentinelaFinalCheck(int CentiIndex) { /* '************************************************* */ /* 'Author: Unknown */ /* 'Last modified: 02/10/2010 */ /* 'Al finalizar el tiempo, se retira y realiza la acción pertinente dependiendo del caso */ /* '03/10/2010: ZaMa - Adaptado para que funcione mas de un centinela en paralelo. */ /* '************************************************* */ int UserIndex; std::string UserName; UserIndex = Centinela[CentiIndex].RevisandoUserIndex; if (!UserList[UserIndex].flags.CentinelaOK) { UserName = UserList[UserIndex].Name; /* 'Logueamos el evento */ LogCentinela("Centinela ejecuto y echó a " + UserName + " por uso de macro inasistido."); /* 'Avisamos a los admins */ SendData(SendTarget_ToAdmins, 0, dakara::protocol::server::BuildConsoleMsg( "Servidor> El centinela ha ejecutado a " + UserName + " y lo echó del juego.", FontTypeNames_FONTTYPE_SERVER)); /* ' Evitamos loguear el logout */ Centinela[CentiIndex].RevisandoUserIndex = 0; WriteShowMessageBox(UserIndex, "Has sido ejecutado por macro inasistido y echado del juego."); UserDie(UserIndex); FlushBuffer(UserIndex); CloseSocket(UserIndex); } Centinela[CentiIndex].clave = 0; Centinela[CentiIndex].TiempoRestante = 0; Centinela[CentiIndex].RevisandoUserIndex = 0; Centinela[CentiIndex].Activo = false; if (Centinela[CentiIndex].NpcIndex != 0) { QuitarNPC(Centinela[CentiIndex].NpcIndex); Centinela[CentiIndex].NpcIndex = 0; } }
void ResetCentinelas() { /* '************************************************* */ /* 'Author: ZaMa */ /* 'Last modified: 02/10/2010 */ /* 'Resetea todos los centinelas */ /* '************************************************* */ int index; int UserIndex; for (index = (vb6::LBound(Centinela)); index <= (vb6::UBound(Centinela)); index++) { /* ' Si esta activo, reseteo toda la info y quito el npc */ if (Centinela[index].Activo) { Centinela[index].Activo = false; UserIndex = Centinela[index].RevisandoUserIndex; if (UserIndex != 0) { UserList[UserIndex].flags.CentinelaIndex = 0; UserList[UserIndex].flags.CentinelaOK = false; Centinela[index].RevisandoUserIndex = 0; } Centinela[index].clave = 0; Centinela[index].TiempoRestante = 0; if (Centinela[index].NpcIndex != 0) { QuitarNPC(Centinela[index].NpcIndex); Centinela[index].NpcIndex = 0; } } } DetenerAsignacion = false; RenovarResetTimer(); }
void WarpCentinela(int UserIndex, int CentinelaIndex) { /* '************************************************* */ /* 'Author: Unknown */ /* 'Last modified: 02/10/2010 */ /* 'Inciamos la revisión del usuario UserIndex */ /* '02/10/2010: ZaMa - Adaptado para que funcione mas de un centinela en paralelo. */ /* '************************************************* */ /* 'Evitamos conflictos de índices */ if (Centinela[CentinelaIndex].NpcIndex != 0) { QuitarNPC(Centinela[CentinelaIndex].NpcIndex); Centinela[CentinelaIndex].NpcIndex = 0; } /* ' Spawn it */ Centinela[CentinelaIndex].NpcIndex = SpawnNpc(NPC_CENTINELA, UserList[UserIndex].Pos, true, false); /* 'Si no pudimos crear el NPC, seguimos esperando a poder hacerlo */ if (Centinela[CentinelaIndex].NpcIndex == 0) { Centinela[CentinelaIndex].RevisandoUserIndex = 0; Centinela[CentinelaIndex].Activo = false; } }
int SpawnNpc(int NpcIndex, struct WorldPos Pos, bool FX, bool Respawn) { int retval; /* '*************************************************** */ /* 'Autor: Unknown (orginal version) */ /* 'Last Modification: 06/15/2008 */ /* '23/01/2007 -> Pablo (ToxicWaste): Creates an NPC of the type Npcindex */ /* '06/15/2008 -> Optimizé el codigo. (NicoNZ) */ /* '*************************************************** */ struct WorldPos newpos; struct WorldPos altpos; int nIndex; bool PosicionValida; bool PuedeAgua; bool PuedeTierra; int Map; int X; int Y; /* 'Conseguimos un indice */ nIndex = OpenNPC(NpcIndex, Respawn); if (nIndex > MAXNPCS) { retval = 0; return retval; } PuedeAgua = Npclist[nIndex].flags.AguaValida; PuedeTierra = Npclist[nIndex].flags.TierraInvalida != 1; /* 'Nos devuelve la posicion valida mas cercana */ ClosestLegalPos(Pos, newpos, PuedeAgua, PuedeTierra); ClosestLegalPos(Pos, altpos, PuedeAgua); /* 'Si X e Y son iguales a 0 significa que no se encontro posicion valida */ if (newpos.X != 0 && newpos.Y != 0) { /* 'Asignamos las nuevas coordenas solo si son validas */ Npclist[nIndex].Pos.Map = newpos.Map; Npclist[nIndex].Pos.X = newpos.X; Npclist[nIndex].Pos.Y = newpos.Y; PosicionValida = true; } else { if (altpos.X != 0 && altpos.Y != 0) { Npclist[nIndex].Pos.Map = altpos.Map; Npclist[nIndex].Pos.X = altpos.X; Npclist[nIndex].Pos.Y = altpos.Y; PosicionValida = true; } else { PosicionValida = false; } } if (!PosicionValida) { QuitarNPC(nIndex); retval = 0; return retval; } /* 'asignamos las nuevas coordenas */ Map = newpos.Map; X = Npclist[nIndex].Pos.X; Y = Npclist[nIndex].Pos.Y; /* 'Crea el NPC */ MakeNPCChar(true, Map, nIndex, Map, X, Y); if (FX) { SendData(SendTarget_ToNPCArea, nIndex, dakara::protocol::server::BuildPlayWave(SND_WARP, X, Y)); SendData(SendTarget_ToNPCArea, nIndex, dakara::protocol::server::BuildCreateFX(Npclist[nIndex].Char.CharIndex, FXIDs_FXWARP, 0)); } retval = nIndex; return retval; }
void MuereNpc(int NpcIndex, int UserIndex) { /* '******************************************************** */ /* 'Author: Unknown */ /* 'Llamado cuando la vida de un NPC llega a cero. */ /* 'Last Modify Date: 13/07/2010 */ /* '22/06/06: (Nacho) Chequeamos si es pretoriano */ /* '24/01/2007: Pablo (ToxicWaste): Agrego para actualización de tag si cambia de status. */ /* '22/05/2010: ZaMa - Los caos ya no suben nobleza ni plebe al atacar npcs. */ /* '23/05/2010: ZaMa - El usuario pierde la pertenencia del npc. */ /* '13/07/2010: ZaMa - Optimizaciones de logica en la seleccion de pretoriano, y el posible cambio de alencion del usuario. */ /* '******************************************************** */ struct npc MiNPC; MiNPC = Npclist[NpcIndex]; bool EraCriminal; /* ' Es pretoriano? */ if (MiNPC.NPCtype == eNPCType_Pretoriano) { // ClanPretoriano[MiNPC.ClanIndex].MuerePretoriano(NpcIndex); } /* 'Quitamos el npc */ QuitarNPC(NpcIndex); /* ' Lo mato un usuario? */ if (UserIndex > 0) { if (MiNPC.flags.Snd3 > 0) { SendData(SendTarget_ToPCArea, UserIndex, dakara::protocol::server::BuildPlayWave(MiNPC.flags.Snd3, MiNPC.Pos.X, MiNPC.Pos.Y)); } UserList[UserIndex].flags.TargetNPC = 0; UserList[UserIndex].flags.TargetNpcTipo = eNPCType_Comun; /* 'El user que lo mato tiene mascotas? */ if (UserList[UserIndex].NroMascotas > 0) { int T; for (T = (1); T <= (MAXMASCOTAS); T++) { if (UserList[UserIndex].MascotasIndex[T] > 0) { if (Npclist[UserList[UserIndex].MascotasIndex[T]].TargetNPC == NpcIndex) { FollowAmo(UserList[UserIndex].MascotasIndex[T]); } } } } /* '[KEVIN] */ if (MiNPC.flags.ExpCount > 0) { if (UserList[UserIndex].PartyIndex > 0) { ObtenerExito(UserIndex, MiNPC.flags.ExpCount, MiNPC.Pos.Map, MiNPC.Pos.X, MiNPC.Pos.Y); } else { UserList[UserIndex].Stats.Exp = UserList[UserIndex].Stats.Exp + MiNPC.flags.ExpCount; if (UserList[UserIndex].Stats.Exp > MAXEXP) { UserList[UserIndex].Stats.Exp = MAXEXP; } WriteConsoleMsg(UserIndex, "Has ganado " + vb6::CStr(MiNPC.flags.ExpCount) + " puntos de experiencia.", FontTypeNames_FONTTYPE_FIGHT); } MiNPC.flags.ExpCount = 0; } /* '[/KEVIN] */ WriteConsoleMsg(UserIndex, "¡Has matado a la criatura!", FontTypeNames_FONTTYPE_FIGHT); if (UserList[UserIndex].Stats.NPCsMuertos < 32000) { UserList[UserIndex].Stats.NPCsMuertos = UserList[UserIndex].Stats.NPCsMuertos + 1; } EraCriminal = criminal(UserIndex); if (MiNPC.Stats.Alineacion == 0) { if (MiNPC.Numero == Guardias) { UserList[UserIndex].Reputacion.NobleRep = 0; UserList[UserIndex].Reputacion.PlebeRep = 0; UserList[UserIndex].Reputacion.AsesinoRep = UserList[UserIndex].Reputacion.AsesinoRep + 500; if (UserList[UserIndex].Reputacion.AsesinoRep > MAXREP) { UserList[UserIndex].Reputacion.AsesinoRep = MAXREP; } } if (MiNPC.MaestroUser == 0) { UserList[UserIndex].Reputacion.AsesinoRep = UserList[UserIndex].Reputacion.AsesinoRep + vlASESINO; if (UserList[UserIndex].Reputacion.AsesinoRep > MAXREP) { UserList[UserIndex].Reputacion.AsesinoRep = MAXREP; } } } else if (!esCaos(UserIndex)) { if (MiNPC.Stats.Alineacion == 1) { UserList[UserIndex].Reputacion.PlebeRep = UserList[UserIndex].Reputacion.PlebeRep + vlCAZADOR; if (UserList[UserIndex].Reputacion.PlebeRep > MAXREP) { UserList[UserIndex].Reputacion.PlebeRep = MAXREP; } } else if (MiNPC.Stats.Alineacion == 2) { UserList[UserIndex].Reputacion.NobleRep = UserList[UserIndex].Reputacion.NobleRep + vlASESINO / 2; if (UserList[UserIndex].Reputacion.NobleRep > MAXREP) { UserList[UserIndex].Reputacion.NobleRep = MAXREP; } } else if (MiNPC.Stats.Alineacion == 4) { UserList[UserIndex].Reputacion.PlebeRep = UserList[UserIndex].Reputacion.PlebeRep + vlCAZADOR; if (UserList[UserIndex].Reputacion.PlebeRep > MAXREP) { UserList[UserIndex].Reputacion.PlebeRep = MAXREP; } } } bool EsCriminal; EsCriminal = criminal(UserIndex); /* ' Cambio de alienacion? */ if (EraCriminal != EsCriminal) { /* ' Se volvio pk? */ if (EsCriminal) { if (esArmada(UserIndex)) { ExpulsarFaccionReal(UserIndex); } /* ' Se volvio ciuda */ } else { if (esCaos(UserIndex)) { ExpulsarFaccionCaos(UserIndex); } } RefreshCharStatus(UserIndex); } CheckUserLevel(UserIndex); if (NpcIndex == UserList[UserIndex].flags.ParalizedByNpcIndex) { RemoveParalisis(UserIndex); } /* ' Userindex > 0 */ } if (MiNPC.MaestroUser == 0) { /* 'Tiramos el inventario */ NPC_TIRAR_ITEMS(MiNPC, MiNPC.NPCtype == eNPCType_Pretoriano); /* 'ReSpawn o no */ ReSpawnNpc(MiNPC); } }
int CrearNPC(int NroNPC, int mapa, struct WorldPos OrigPos, int CustomHead) { int retval = 0; /* '*************************************************** */ /* 'Author: Unknown */ /* 'Last Modification: - */ /* ' */ /* '*************************************************** */ /* 'Crea un NPC del tipo NRONPC */ struct WorldPos Pos; struct WorldPos newpos; struct WorldPos altpos; int nIndex; bool PosicionValida = false; int Iteraciones = 0; bool PuedeAgua; bool PuedeTierra; int Map; int X; int Y; /* 'Conseguimos un indice */ nIndex = OpenNPC(NroNPC); if (nIndex > MAXNPCS) { return retval; } /* ' Cabeza customizada */ if (CustomHead != 0) { Npclist[nIndex].Char.Head = CustomHead; } PuedeAgua = Npclist[nIndex].flags.AguaValida; PuedeTierra = vb6::IIf(Npclist[nIndex].flags.TierraInvalida == 1, false, true); /* 'Necesita ser respawned en un lugar especifico */ if (InMapBounds(OrigPos.Map, OrigPos.X, OrigPos.Y)) { Map = OrigPos.Map; X = OrigPos.X; Y = OrigPos.Y; Npclist[nIndex].Orig = OrigPos; Npclist[nIndex].Pos = OrigPos; } else { /* 'mapa */ Pos.Map = mapa; altpos.Map = mapa; while (!PosicionValida) { /* 'Obtenemos posicion al azar en x */ Pos.X = RandomNumber(MinXBorder, MaxXBorder); /* 'Obtenemos posicion al azar en y */ Pos.Y = RandomNumber(MinYBorder, MaxYBorder); /* 'Nos devuelve la posicion valida mas cercana */ ClosestLegalPos(Pos, newpos, PuedeAgua, PuedeTierra); if (newpos.X != 0 && newpos.Y != 0) { altpos.X = newpos.X; /* 'posicion alternativa (para evitar el anti respawn, pero intentando qeu si tenía que ser en el agua, sea en el agua.) */ altpos.Y = newpos.Y; } else { ClosestLegalPos(Pos, newpos, PuedeAgua); if (newpos.X != 0 && newpos.Y != 0) { altpos.X = newpos.X; /* 'posicion alternativa (para evitar el anti respawn) */ altpos.Y = newpos.Y; } } /* 'Si X e Y son iguales a 0 significa que no se encontro posicion valida */ if (LegalPosNPC(newpos.Map, newpos.X, newpos.Y, PuedeAgua) && !HayPCarea(newpos) && TestSpawnTrigger(newpos, PuedeAgua)) { /* 'Asignamos las nuevas coordenas solo si son validas */ Npclist[nIndex].Pos.Map = newpos.Map; Npclist[nIndex].Pos.X = newpos.X; Npclist[nIndex].Pos.Y = newpos.Y; PosicionValida = true; } else { newpos.X = 0; newpos.Y = 0; } /* 'for debug */ Iteraciones = Iteraciones + 1; if (Iteraciones > MAXSPAWNATTEMPS) { if (altpos.X != 0 && altpos.Y != 0) { Map = altpos.Map; X = altpos.X; Y = altpos.Y; Npclist[nIndex].Pos.Map = Map; Npclist[nIndex].Pos.X = X; Npclist[nIndex].Pos.Y = Y; MakeNPCChar(true, Map, nIndex, Map, X, Y); return retval; } else { altpos.X = 50; altpos.Y = 50; ClosestLegalPos(altpos, newpos); if (newpos.X != 0 && newpos.Y != 0) { Npclist[nIndex].Pos.Map = newpos.Map; Npclist[nIndex].Pos.X = newpos.X; Npclist[nIndex].Pos.Y = newpos.Y; MakeNPCChar(true, newpos.Map, nIndex, newpos.Map, newpos.X, newpos.Y); return retval; } else { QuitarNPC(nIndex); LogError( vb6::CStr(MAXSPAWNATTEMPS) + " iteraciones en CrearNpc Mapa:" + vb6::CStr(mapa) + " NroNpc:" + vb6::CStr(NroNPC)); return retval; } } } } /* 'asignamos las nuevas coordenas */ Map = newpos.Map; X = Npclist[nIndex].Pos.X; Y = Npclist[nIndex].Pos.Y; } /* 'Crea el NPC */ MakeNPCChar(true, Map, nIndex, Map, X, Y); retval = nIndex; return retval; }
void PasarMinutoCentinela() { /* '************************************************* */ /* 'Author: Unknown */ /* 'Last modified: 02/10/2010 */ /* 'Control del timer. Llamado cada un minuto. */ /* '03/10/2010: ZaMa - Adaptado para que funcione mas de un centinela en paralelo. */ /* '************************************************* */ int index; int UserIndex; int IdleCount = 0; if (!centinelaActivado) { return; } /* ' Primero reviso los que estan chequeando usuarios */ for (index = (1); index <= (NRO_CENTINELA); index++) { /* ' Esta activo? */ if (Centinela[index].Activo) { Centinela[index].TiempoRestante = Centinela[index].TiempoRestante - 1; /* ' Temrino el tiempo de chequeo? */ if (Centinela[index].TiempoRestante == 0) { CentinelaFinalCheck(index); } else { UserIndex = Centinela[index].RevisandoUserIndex; /* 'RECORDamos al user que debe escribir */ if (Distancia(Npclist[Centinela[index].NpcIndex].Pos, UserList[UserIndex].Pos) > 5) { WarpCentinela(UserIndex, index); } /* 'El centinela habla y se manda a consola para que no quepan dudas */ WriteChatOverHead(UserIndex, "¡" + UserList[UserIndex].Name + ", tienes un minuto más para responder! Debes escribir /CENTINELA " + vb6::CStr(Centinela[index].clave) + ".", (Npclist[Centinela[index].NpcIndex].Char.CharIndex), vbRed); WriteConsoleMsg(UserIndex, "¡" + UserList[UserIndex].Name + ", tienes un minuto más para responder!", FontTypeNames_FONTTYPE_CENTINELA); FlushBuffer(UserIndex); } } else { /* ' Lo reseteo aca, para que pueda hablarle al usuario chequeado aunque haya respondido bien. */ if (Centinela[index].NpcIndex != 0) { if (Centinela[index].RevisandoUserIndex != 0) { UserList[Centinela[index].RevisandoUserIndex].flags.CentinelaIndex = 0; Centinela[index].RevisandoUserIndex = 0; } QuitarNPC(Centinela[index].NpcIndex); Centinela[index].NpcIndex = 0; } IdleCount = IdleCount + 1; } } /* 'Verificamos si ya debemos resetear la lista */ int TActual; TActual = vb6::GetTickCount(); if (checkInterval(centinelaStartTime, TActual, centinelaInterval)) { /* ' Espero a que terminen de controlar todos los centinelas */ DetenerAsignacion = true; } /* ' Si hay algun centinela libre, se fija si no hay trabajadores disponibles para chequear */ if (IdleCount != 0) { /* ' Si es tiempo de resetear flags, chequeo que no quede nadie activo */ if (DetenerAsignacion) { /* ' No se completaron los ultimos chequeos */ if (IdleCount < NRO_CENTINELA) { return; } /* ' Resetea todos los flags */ ResetCentinelaInfo(); DetenerAsignacion = false; /* ' Renuevo el contador de reseteo */ RenovarResetTimer(); } GoToNextWorkingChar(); } }