// // 按ID排序增加当前连线记录 // int AddDirection( IN PPACKET_DIRECTION pPacketDirection ) { static int Index, MoveCount; dprintf("-->AddDirection, CurrentCount: %d, ID:%u\n", m_DirectionCount, pPacketDirection->Id); if(pPacketDirection == NULL || pPacketDirection->Id == 0) return -1; if(FindDirection(pPacketDirection->Id, &Index)) { m_PacketDirection[Index] = *pPacketDirection; return Index; } if(Index >= MAX_PACKET_ONLINE) return -1; MoveCount = m_DirectionCount - Index; dprintf("-->AddDirection, Index:%d, MoveCount:%d\n", Index, MoveCount); if(MoveCount > 0) { memcpy(m_PacketDirection + Index + 1 , m_PacketDirection + Index , MoveCount * PACKET_DIRECTION_LENGTH); } m_PacketDirection[Index] = *pPacketDirection; m_DirectionCount++; dprintf("<--AddDirection, %d\n", m_DirectionCount); return Index; }
void PersigueCiudadano(int NpcIndex) { /* '*************************************************** */ /* 'Autor: Unknown (orginal version) */ /* 'Last Modification: 12/01/2010 (ZaMa) */ /* '14/09/2009: ZaMa - Now npcs don't follow protected users. */ /* '12/01/2010: ZaMa - Los npcs no atacan druidas mimetizados con npcs. */ /* '*************************************************** */ int UserIndex; int tHeading; int i; bool UserProtected; for (i = (1); i <= (ConnGroups[Npclist[NpcIndex].Pos.Map].CountEntrys); i++) { UserIndex = ConnGroups[Npclist[NpcIndex].Pos.Map].UserEntrys[i]; /* 'Is it in it's range of vision?? */ if (vb6::Abs(UserList[UserIndex].Pos.X - Npclist[NpcIndex].Pos.X) <= RANGO_VISION_X) { if (vb6::Abs(UserList[UserIndex].Pos.Y - Npclist[NpcIndex].Pos.Y) <= RANGO_VISION_Y) { if (!criminal(UserIndex)) { UserProtected = !IntervaloPermiteSerAtacado(UserIndex) && UserList[UserIndex].flags.NoPuedeSerAtacado; UserProtected = UserProtected || UserList[UserIndex].flags.Ignorado || UserList[UserIndex].flags.EnConsulta; if (UserList[UserIndex].flags.Muerto == 0 && UserList[UserIndex].flags.invisible == 0 && UserList[UserIndex].flags.Oculto == 0 && UserList[UserIndex].flags.AdminPerseguible && !UserProtected) { if (Npclist[NpcIndex].flags.LanzaSpells > 0) { NpcLanzaUnSpell(NpcIndex, UserIndex); } tHeading = FindDirection(Npclist[NpcIndex].Pos, UserList[UserIndex].Pos); MoveNPCChar(NpcIndex, tHeading); return; } } } } } RestoreOldMovement(NpcIndex); }
// // 删除当前连线记录 // int DeleteDirection(ULONG Id, BOOL DelIn, BOOL DelOut) { static int Index, MoveCount, i; dprintf("-->DeleteDirection, DelIn(%d), DelOut(%d), Id(%u)\n", DelIn, DelOut, Id); if(Id == 0 || !FindDirection(Id, &Index)) return -1; dprintf("-->DeleteDirection, Index:%d\n", Index); if(DelIn) m_PacketDirection[Index].DeleteIn = DelIn; if(DelOut) m_PacketDirection[Index].DeleteOut = DelOut; if(!m_PacketDirection[Index].DeleteIn || !m_PacketDirection[Index].DeleteOut) return -1; for(i = 0; i < MAX_PACKET_ONLINE; i++) { if(m_DeleteDirection[i].Id == 0) { m_DeleteDirection[i] = m_PacketDirection[Index]; break; } } MoveCount = m_DirectionCount - Index - 1; dprintf("-->DeleteDirection, MoveCount:%d, Id:%u\n", MoveCount, m_PacketDirection[Index].Id); if(MoveCount > 0) { memcpy(m_PacketDirection + Index , m_PacketDirection + Index + 1 , MoveCount * PACKET_DIRECTION_LENGTH); } else { m_PacketDirection[Index].Id = 0; } m_DirectionCount--; dprintf("<--DeleteDirection, %d\n", m_DirectionCount); return 0; }
////////////////////////////////////////////////////////////////////////////////// /// Sets the actor to the correct walking animation as she/he walks a path. void Actor::UpdateActorWalkingAnimation(long xPos, long yPos) { SetAutoAnimate(true); FindDirection(xPos, yPos); if(direction.x == 1 && direction.y == 0 && GetCurAnimation() != WALKING_RIGHT) { SetAnimation(WALKING_RIGHT); } else if(direction.x == 1 && direction.y == -1 && GetCurAnimation() != WALKING_RIGHT) { SetAnimation(WALKING_RIGHT); } else if(direction.x == 0 && direction.y == -1 && GetCurAnimation() != WALKING_FRONT) { SetAnimation(WALKING_FRONT); } else if(direction.x == -1 && direction.y == -1 && GetCurAnimation() != WALKING_LEFT) { SetAnimation(WALKING_LEFT); } else if(direction.x == -1 && direction.y == 0 && GetCurAnimation() != WALKING_LEFT) { SetAnimation(WALKING_LEFT); } else if(direction.x == -1 && direction.y == 1 && GetCurAnimation() != WALKING_LEFT) { SetAnimation(WALKING_LEFT); } else if(direction.x == 0 && direction.y == 1 && GetCurAnimation() != WALKING_BACK) { SetAnimation(WALKING_BACK); } else if(direction.x == 1 && direction.y == 1 && GetCurAnimation() != WALKING_RIGHT) { SetAnimation(WALKING_RIGHT); } }
void SeguirAmo(int NpcIndex) { /* '*************************************************** */ /* 'Author: Unknown */ /* 'Last Modification: - */ /* ' */ /* '*************************************************** */ int tHeading; int UI; if (Npclist[NpcIndex].Target == 0 && Npclist[NpcIndex].TargetNPC == 0) { UI = Npclist[NpcIndex].MaestroUser; if (UI > 0) { /* 'Is it in it's range of vision?? */ if (vb6::Abs(UserList[UI].Pos.X - Npclist[NpcIndex].Pos.X) <= RANGO_VISION_X) { if (vb6::Abs(UserList[UI].Pos.Y - Npclist[NpcIndex].Pos.Y) <= RANGO_VISION_Y) { if (UserList[UI].flags.Muerto == 0 && UserList[UI].flags.invisible == 0 && UserList[UI].flags.Oculto == 0 && Distancia(Npclist[NpcIndex].Pos, UserList[UI].Pos) > 3) { tHeading = FindDirection(Npclist[NpcIndex].Pos, UserList[UI].Pos); MoveNPCChar(NpcIndex, tHeading); return; } } } } } RestoreOldMovement(NpcIndex); }
bool FollowPath(int NpcIndex) { bool retval = true; /* '*************************************************** */ /* 'Author: Gulfas Morgolock */ /* 'Last Modification: - */ /* 'Moves the npc. */ /* '*************************************************** */ struct WorldPos tmpPos; int tHeading; tmpPos.Map = Npclist[NpcIndex].Pos.Map; /* ' invert� las coordenadas */ tmpPos.X = Npclist[NpcIndex].PFINFO.Path[Npclist[NpcIndex].PFINFO.CurPos].X; tmpPos.Y = Npclist[NpcIndex].PFINFO.Path[Npclist[NpcIndex].PFINFO.CurPos].Y; /* 'Debug.Print "(" & tmpPos.X & "," & tmpPos.Y & ")" */ tHeading = FindDirection(Npclist[NpcIndex].Pos, tmpPos); MoveNPCChar(NpcIndex, tHeading); Npclist[NpcIndex].PFINFO.CurPos = Npclist[NpcIndex].PFINFO.CurPos + 1; return retval; }
void LAYER::LayPath( int32_t wX, int32_t wY ) { int DeltaDir; LOGICAL bLoop = FALSE, bIsRetry; // no looping.... int tx, ty; int nPathLayed = 0; int nDir, nNewDir; LOGICAL bBackTrace = FALSE, bFailed = FALSE; PLAYER_PATH_NODE node; lprintf( WIDE("Laying path %p to %d,%d"), this, wX, wY ); node = (PLAYER_PATH_NODE)PeekData( &pds_path ); // sanity validations... // being done already, etc... wX -= LAYER::x; wY -= LAYER::y; if( node ) { if( node->x == wX && node->y == wY ) { lprintf( WIDE("Already at this end point, why are you telling me to end where I already did?") ); return; } // should range check wX and wY to sane limits // but for now we'll trust the programmer... if( abs( node->x - wX ) > 100 || abs( node->y - wY ) > 100 ) { DebugBreak(); lprintf( WIDE("Laying a LONG path - is this okay?!") ); } } #ifdef DEBUG_BACKTRACE Log( WIDE("Enter...") ); #endif //------------ FORWARD DRAWING NOW ..... bIsRetry = FALSE; DeltaDir = 0; { PLAYER_PATH_NODE node; // get the last node in the path. node = (PLAYER_PATH_NODE)PeekData( &pds_path ); while( node ) { nNewDir = FindDirection( node->x , node->y , wX, wY ); if( nNewDir == NOWHERE ) { // already have this node at the current spot... lprintf( WIDE("Node has ended here...") ); break; } nDir = NOWHERE; // intialize this, in case we missed a path below... if( node->flags.BackDir == NOWHERE ) { // if it is newdir, we're okay to go ahead with this plan. if( node->flags.ForeDir != nNewDir && flags.bForced ) { lprintf( WIDE("Have a forced begin point, and no way to get there from here....") ); DebugBreak(); if( NearDir( node->flags.ForeDir, nNewDir ) == 10 ) { lprintf( WIDE("MUST go %d , have to go %d from here. Go nowhere."), node->flags.ForeDir, nNewDir ); lprintf( WIDE("Okay - consider a arbitrary jump to go forward... until we can go backward.") ); } else { lprintf( WIDE("It's just not quite right... return, a less radical assumption may be made.") ); } return; } // else, just go ahead, we returned above here. node->flags.ForeDir = nNewDir; } else { // need to determine a valid foredir based on nNewDir desire, and nBackDir given. lprintf( WIDE("%d, %d = %d") , Opposite( node->flags.BackDir ) , nNewDir , NearDir(Opposite( node->flags.BackDir ) , nNewDir ) ); lprintf( WIDE("newdir = %d backdir = %d"), nNewDir, node->flags.BackDir ); //pold->TopLayer->ForeDir; if( NearDir( nNewDir, Opposite( node->flags.BackDir ) ) != 10 ) { // this is a valid direction to go. node->flags.ForeDir = nNewDir; } else { lprintf( WIDE("Unlay path cause we can't get there from here.") ); node = UnlayPath( nPathLayed + 1 ); // at this point always unlay at least one more than we put down. nPathLayed = 1; continue; #if 0 int nBase = Opposite( node->flags.BackDir ); nDir = ( node->flags.BackDir + 2 ) & 7; if( NearDir( nNewDir, nDir ) != 10 ) { //node->flags.ForeDir = (nBase + 6) &7; node->flags.ForeDir = Right( nBase ); } else if( NearDir( nNewDir, Opposite( nDir ) ) != 10 ) { node->flags.ForeDir = Left(nBase); } else { // this should be a random chance to go left or right... // maybe tend to the lower x or higher x ? lprintf( WIDE("Choosing an arbitrary directino of 1, and only on1") ); //node->flags.ForeDir = Right( nBase + 1 ); node->flags.bFlopped = 0; node->flags.bTry = 1; node->flags.bForced = 1; node->flags.ForeDir = LeftOrRight( nBase, node->flags.bFlopped ); // set a flag in this node for which way to go... // but a left/right node needs the ability // to remain forced for a single unlay, and move in a direction... } #endif } } { int n; tx = node->x + DirDeltaMap[node->flags.ForeDir].x; ty = node->y + DirDeltaMap[node->flags.ForeDir].y; lprintf( WIDE("New coordinate will be %d,%d"), tx, ty ); if( n = Overlaps( tx, ty ) ) // aleady drew something here... // the distance of the overlap is n layers, including Nth layer // for( ; n; PopData(&pds_stack), n-- ) // and some fixups which unlay path does. { lprintf( WIDE("Unlaying path %d steps to overlap") , n ); node = UnlayPath( n ); // at an unlay point of forced, unlay path should be 'smart' and 'wait' // otherwise we may unwind to our tail and be confused... specially when moving away // and coming back to reside at the center. // if the force direction to go from a forced node is excessive, that definatly // breaks force, and releases the path node. // there may be board conditions which also determine the pathing. // okay try this again from the top do { // startin laying path again. continue; } // otherwise we're good to go foreward. // at least we won't add this node if it would have // already been there, heck, other than that via's // don't exist, sometimes we'll even get the exact node // that this should be.... { LAYER_PATH_NODE newnode; // this may be set intrinsically by being an excessive force // causing a large direction delta newnode.flags.bForced = FALSE; newnode.flags.ForeDir = NOWHERE; // this of course must start(?) exactly how the other ended(?)... newnode.flags.BackDir = Opposite( node->flags.ForeDir ); newnode.x = tx; newnode.y = ty; { int xx = tx + x; int yy = ty + y; if( xx < min_x ) { w += min_x - xx; min_x = xx; } if( xx >= ( min_x + (int32_t)w ) ) w = xx - min_x + 1; if( yy < min_y ) { h += min_y - yy; min_y = yy; } if( yy >= ( min_y + (int32_t)h ) ) h = yy - min_y + 1; } lprintf( WIDE("Push path %d,%d min=%d,%d size=%d,%d"), newnode.x, newnode.y, min_x, min_y, w, h ); PushData( &pds_path, &newnode ); nPathLayed++; node = (PLAYER_PATH_NODE)PeekData( &pds_path ); // okay this is now where we are. } } } } }
void AiNpcAtacaNpc(int NpcIndex) { /* '*************************************************** */ /* 'Author: Unknown */ /* 'Last Modification: - */ /* ' */ /* '*************************************************** */ int tHeading; int X; int Y; int NI; bool bNoEsta = false; int SignoNS; int SignoEO; if (Npclist[NpcIndex].flags.Inmovilizado == 1) { switch (Npclist[NpcIndex].Char.heading) { case eHeading_NORTH: SignoNS = -1; SignoEO = 0; break; case eHeading_EAST: SignoNS = 0; SignoEO = 1; break; case eHeading_SOUTH: SignoNS = 1; SignoEO = 0; break; case eHeading_WEST: SignoEO = -1; SignoNS = 0; break; default: SignoEO = SignoNS = 0; break; } for (Y = (Npclist[NpcIndex].Pos.Y); ((vb6::IIf(SignoNS == 0, 1, SignoNS)) > 0) ? (Y <= (Npclist[NpcIndex].Pos.Y + SignoNS * RANGO_VISION_Y)) : (Y >= (Npclist[NpcIndex].Pos.Y + SignoNS * RANGO_VISION_Y)); Y = Y + (vb6::IIf(SignoNS == 0, 1, SignoNS))) { for (X = (Npclist[NpcIndex].Pos.X); ((vb6::IIf(SignoEO == 0, 1, SignoEO)) > 0) ? (X <= (Npclist[NpcIndex].Pos.X + SignoEO * RANGO_VISION_X)) : (X >= (Npclist[NpcIndex].Pos.X + SignoEO * RANGO_VISION_X)); X = X + (vb6::IIf(SignoEO == 0, 1, SignoEO))) { if (X >= MinXBorder && X <= MaxXBorder && Y >= MinYBorder && Y <= MaxYBorder) { NI = MapData[Npclist[NpcIndex].Pos.Map][X][Y].NpcIndex; if (NI > 0) { if (Npclist[NpcIndex].TargetNPC == NI) { bNoEsta = true; if (Npclist[NpcIndex].Numero == ELEMENTALFUEGO) { NpcLanzaUnSpellSobreNpc(NpcIndex, NI); if (Npclist[NI].NPCtype == eNPCType_DRAGON) { Npclist[NI].CanAttack = 1; NpcLanzaUnSpellSobreNpc(NI, NpcIndex); } } else { /* 'aca verificamosss la distancia de ataque */ if (Distancia(Npclist[NpcIndex].Pos, Npclist[NI].Pos) <= 1) { NpcAtacaNpc(NpcIndex, NI); } } return; } } } } } } else { for (Y = (Npclist[NpcIndex].Pos.Y - RANGO_VISION_Y); Y <= (Npclist[NpcIndex].Pos.Y + RANGO_VISION_Y); Y++) { for (X = (Npclist[NpcIndex].Pos.X - RANGO_VISION_Y); X <= (Npclist[NpcIndex].Pos.X + RANGO_VISION_Y); X++) { if (X >= MinXBorder && X <= MaxXBorder && Y >= MinYBorder && Y <= MaxYBorder) { NI = MapData[Npclist[NpcIndex].Pos.Map][X][Y].NpcIndex; if (NI > 0) { if (Npclist[NpcIndex].TargetNPC == NI) { bNoEsta = true; if (Npclist[NpcIndex].Numero == ELEMENTALFUEGO) { NpcLanzaUnSpellSobreNpc(NpcIndex, NI); if (Npclist[NI].NPCtype == eNPCType_DRAGON) { Npclist[NI].CanAttack = 1; NpcLanzaUnSpellSobreNpc(NI, NpcIndex); } } else { /* 'aca verificamosss la distancia de ataque */ if (Distancia(Npclist[NpcIndex].Pos, Npclist[NI].Pos) <= 1) { NpcAtacaNpc(NpcIndex, NI); } } if (Npclist[NpcIndex].flags.Inmovilizado == 1) { return; } if (Npclist[NpcIndex].TargetNPC == 0) { return; } tHeading = FindDirection(Npclist[NpcIndex].Pos, Npclist[MapData[Npclist[NpcIndex].Pos.Map][X][Y].NpcIndex].Pos); MoveNPCChar(NpcIndex, tHeading); return; } } } } } } if (!bNoEsta) { if (Npclist[NpcIndex].MaestroUser > 0) { FollowAmo(NpcIndex); } else { Npclist[NpcIndex].Movement = Npclist[NpcIndex].flags.OldMovement; Npclist[NpcIndex].Hostile = Npclist[NpcIndex].flags.OldHostil; } } }
void PersigueCriminal(int NpcIndex) { /* '*************************************************** */ /* 'Autor: Unknown (orginal version) */ /* 'Last Modification: 12/01/2010 (ZaMa) */ /* '14/09/2009: ZaMa - Now npcs don't follow protected users. */ /* '12/01/2010: ZaMa - Los npcs no atacan druidas mimetizados con npcs. */ /* '*************************************************** */ int UserIndex; int tHeading; int i; int SignoNS; int SignoEO; bool UserProtected; if (Npclist[NpcIndex].flags.Inmovilizado == 1) { switch (Npclist[NpcIndex].Char.heading) { case eHeading_NORTH: SignoNS = -1; SignoEO = 0; break; case eHeading_EAST: SignoNS = 0; SignoEO = 1; break; case eHeading_SOUTH: SignoNS = 1; SignoEO = 0; break; case eHeading_WEST: SignoEO = -1; SignoNS = 0; break; default: SignoEO = SignoNS = 0; break; } for (i = (1); i <= (ConnGroups[Npclist[NpcIndex].Pos.Map].CountEntrys); i++) { UserIndex = ConnGroups[Npclist[NpcIndex].Pos.Map].UserEntrys[i]; /* 'Is it in it's range of vision?? */ if (vb6::Abs(UserList[UserIndex].Pos.X - Npclist[NpcIndex].Pos.X) <= RANGO_VISION_X && vb6::Sgn(UserList[UserIndex].Pos.X - Npclist[NpcIndex].Pos.X) == SignoEO) { if (vb6::Abs( UserList[UserIndex].Pos.Y - Npclist[NpcIndex].Pos.Y) <= RANGO_VISION_Y && vb6::Sgn(UserList[UserIndex].Pos.Y - Npclist[NpcIndex].Pos.Y) == SignoNS) { if (criminal(UserIndex)) { UserProtected = !IntervaloPermiteSerAtacado(UserIndex) && UserList[UserIndex].flags.NoPuedeSerAtacado; UserProtected = UserProtected || UserList[UserIndex].flags.Ignorado || UserList[UserIndex].flags.EnConsulta; if (UserList[UserIndex].flags.Muerto == 0 && UserList[UserIndex].flags.invisible == 0 && UserList[UserIndex].flags.Oculto == 0 && UserList[UserIndex].flags.AdminPerseguible && !UserProtected) { if (Npclist[NpcIndex].flags.LanzaSpells > 0) { NpcLanzaUnSpell(NpcIndex, UserIndex); } return; } } } } } } else { for (i = (1); i <= (ConnGroups[Npclist[NpcIndex].Pos.Map].CountEntrys); i++) { UserIndex = ConnGroups[Npclist[NpcIndex].Pos.Map].UserEntrys[i]; /* 'Is it in it's range of vision?? */ if (vb6::Abs(UserList[UserIndex].Pos.X - Npclist[NpcIndex].Pos.X) <= RANGO_VISION_X) { if (vb6::Abs( UserList[UserIndex].Pos.Y - Npclist[NpcIndex].Pos.Y) <= RANGO_VISION_Y) { if (criminal(UserIndex)) { UserProtected = !IntervaloPermiteSerAtacado(UserIndex) && UserList[UserIndex].flags.NoPuedeSerAtacado; UserProtected = UserProtected || UserList[UserIndex].flags.Ignorado; if (UserList[UserIndex].flags.Muerto == 0 && UserList[UserIndex].flags.invisible == 0 && UserList[UserIndex].flags.Oculto == 0 && UserList[UserIndex].flags.AdminPerseguible && !UserProtected) { if (Npclist[NpcIndex].flags.LanzaSpells > 0) { NpcLanzaUnSpell(NpcIndex, UserIndex); } if (Npclist[NpcIndex].flags.Inmovilizado == 1) { return; } tHeading = FindDirection(Npclist[NpcIndex].Pos, UserList[UserIndex].Pos); MoveNPCChar(NpcIndex, tHeading); return; } } } } } } RestoreOldMovement(NpcIndex); }
/* ' @param NpcIndex Specifies reference to the npc */ void SeguirAgresor(int NpcIndex) { /* '************************************************************** */ /* 'Author: Unknown */ /* 'Last Modify by: Marco Vanotti (MarKoxX) */ /* 'Last Modify Date: 08/16/2008 */ /* '08/16/2008: MarKoxX - Now pets that do mel� attacks have to be near the enemy to attack. */ /* '************************************************************** */ int tHeading; int UI; int i; int SignoNS; int SignoEO; if (Npclist[NpcIndex].flags.Paralizado == 1 || Npclist[NpcIndex].flags.Inmovilizado == 1) { switch (Npclist[NpcIndex].Char.heading) { case eHeading_NORTH: SignoNS = -1; SignoEO = 0; break; case eHeading_EAST: SignoNS = 0; SignoEO = 1; break; case eHeading_SOUTH: SignoNS = 1; SignoEO = 0; break; case eHeading_WEST: SignoEO = -1; SignoNS = 0; break; default: SignoEO = SignoNS = 0; break; } for (i = (1); i <= (ConnGroups[Npclist[NpcIndex].Pos.Map].CountEntrys); i++) { UI = ConnGroups[Npclist[NpcIndex].Pos.Map].UserEntrys[i]; /* 'Is it in it's range of vision?? */ if (vb6::Abs(UserList[UI].Pos.X - Npclist[NpcIndex].Pos.X) <= RANGO_VISION_X && vb6::Sgn(UserList[UI].Pos.X - Npclist[NpcIndex].Pos.X) == SignoEO) { if (vb6::Abs(UserList[UI].Pos.Y - Npclist[NpcIndex].Pos.Y) <= RANGO_VISION_Y && vb6::Sgn(UserList[UI].Pos.Y - Npclist[NpcIndex].Pos.Y) == SignoNS) { if (UserList[UI].Name == Npclist[NpcIndex].flags.AttackedBy) { if (Npclist[NpcIndex].MaestroUser > 0) { if (!criminal(Npclist[NpcIndex].MaestroUser) && !criminal(UI) && (UserList[Npclist[NpcIndex].MaestroUser].flags.Seguro || UserList[Npclist[NpcIndex].MaestroUser].Faccion.ArmadaReal == 1)) { WriteConsoleMsg(Npclist[NpcIndex].MaestroUser, "La mascota no atacará a ciudadanos si eres miembro del ejército real o tienes el seguro activado.", FontTypeNames_FONTTYPE_INFO); FlushBuffer(Npclist[NpcIndex].MaestroUser); Npclist[NpcIndex].flags.AttackedBy = ""; return; } } if (UserList[UI].flags.Muerto == 0 && UserList[UI].flags.invisible == 0 && UserList[UI].flags.Oculto == 0) { if (Npclist[NpcIndex].flags.LanzaSpells > 0) { NpcLanzaUnSpell(NpcIndex, UI); } else { if (Distancia(UserList[UI].Pos, Npclist[NpcIndex].Pos) <= 1) { /* ' TODO : Set this a separate AI for Elementals and Druid's pets */ if (Npclist[NpcIndex].Numero != 92) { NpcAtacaUser(NpcIndex, UI); } } } return; } } } } } } else { for (i = (1); i <= (ConnGroups[Npclist[NpcIndex].Pos.Map].CountEntrys); i++) { UI = ConnGroups[Npclist[NpcIndex].Pos.Map].UserEntrys[i]; /* 'Is it in it's range of vision?? */ if (vb6::Abs(UserList[UI].Pos.X - Npclist[NpcIndex].Pos.X) <= RANGO_VISION_X) { if (vb6::Abs(UserList[UI].Pos.Y - Npclist[NpcIndex].Pos.Y) <= RANGO_VISION_Y) { if (UserList[UI].Name == Npclist[NpcIndex].flags.AttackedBy) { if (Npclist[NpcIndex].MaestroUser > 0) { if (!criminal(Npclist[NpcIndex].MaestroUser) && !criminal(UI) && (UserList[Npclist[NpcIndex].MaestroUser].flags.Seguro || UserList[Npclist[NpcIndex].MaestroUser].Faccion.ArmadaReal == 1)) { WriteConsoleMsg(Npclist[NpcIndex].MaestroUser, "La mascota no atacará a ciudadanos si eres miembro del ejército real o tienes el seguro activado.", FontTypeNames_FONTTYPE_INFO); FlushBuffer(Npclist[NpcIndex].MaestroUser); Npclist[NpcIndex].flags.AttackedBy = ""; FollowAmo(NpcIndex); return; } } if (UserList[UI].flags.Muerto == 0 && UserList[UI].flags.invisible == 0 && UserList[UI].flags.Oculto == 0) { if (Npclist[NpcIndex].flags.LanzaSpells > 0) { NpcLanzaUnSpell(NpcIndex, UI); } else { if (Distancia(UserList[UI].Pos, Npclist[NpcIndex].Pos) <= 1) { /* ' TODO : Set this a separate AI for Elementals and Druid's pets */ if (Npclist[NpcIndex].Numero != 92) { NpcAtacaUser(NpcIndex, UI); } } } tHeading = FindDirection(Npclist[NpcIndex].Pos, UserList[UI].Pos); MoveNPCChar(NpcIndex, tHeading); return; } } } } } } RestoreOldMovement(NpcIndex); }
void IrUsuarioCercano(int NpcIndex) { /* '*************************************************** */ /* 'Autor: Unknown (orginal version) */ /* 'Last Modification: 25/07/2010 (ZaMa) */ /* '14/09/2009: ZaMa - Now npcs don't follow protected users. */ /* '12/01/2010: ZaMa - Los npcs no atacan druidas mimetizados con npcs */ /* '25/07/2010: ZaMa - Agrego una validacion temporal para evitar que los npcs ataquen a usuarios de mapas difernetes. */ /* '*************************************************** */ int tHeading; int UserIndex; int SignoNS; int SignoEO; int i; bool UserProtected; if (Npclist[NpcIndex].flags.Inmovilizado == 1) { switch (Npclist[NpcIndex].Char.heading) { case eHeading_NORTH: SignoNS = -1; SignoEO = 0; break; case eHeading_EAST: SignoNS = 0; SignoEO = 1; break; case eHeading_SOUTH: SignoNS = 1; SignoEO = 0; break; case eHeading_WEST: SignoEO = -1; SignoNS = 0; break; default: SignoEO = SignoNS = 0; break; } for (i = (1); i <= (ConnGroups[Npclist[NpcIndex].Pos.Map].CountEntrys); i++) { UserIndex = ConnGroups[Npclist[NpcIndex].Pos.Map].UserEntrys[i]; /* 'Is it in it's range of vision?? */ if (vb6::Abs(UserList[UserIndex].Pos.X - Npclist[NpcIndex].Pos.X) <= RANGO_VISION_X && vb6::Sgn(UserList[UserIndex].Pos.X - Npclist[NpcIndex].Pos.X) == SignoEO) { if (vb6::Abs( UserList[UserIndex].Pos.Y - Npclist[NpcIndex].Pos.Y) <= RANGO_VISION_Y && vb6::Sgn(UserList[UserIndex].Pos.Y - Npclist[NpcIndex].Pos.Y) == SignoNS) { UserProtected = !IntervaloPermiteSerAtacado(UserIndex) && UserList[UserIndex].flags.NoPuedeSerAtacado; UserProtected = UserProtected || UserList[UserIndex].flags.Ignorado || UserList[UserIndex].flags.EnConsulta; if (UserList[UserIndex].flags.Muerto == 0) { if (!UserProtected) { if (Npclist[NpcIndex].flags.LanzaSpells != 0) { NpcLanzaUnSpell(NpcIndex, UserIndex); } return; } } } } } /* ' No esta inmobilizado */ } else { /* ' Tiene prioridad de seguir al usuario al que le pertenece si esta en el rango de vision */ int OwnerIndex; OwnerIndex = Npclist[NpcIndex].Owner; if (OwnerIndex > 0) { /* ' TODO: Es temporal hatsa reparar un bug que hace que ataquen a usuarios de otros mapas */ if (UserList[OwnerIndex].Pos.Map == Npclist[NpcIndex].Pos.Map) { /* 'Is it in it's range of vision?? */ if (vb6::Abs( UserList[OwnerIndex].Pos.X - Npclist[NpcIndex].Pos.X) <= RANGO_VISION_X) { if (vb6::Abs( UserList[OwnerIndex].Pos.Y - Npclist[NpcIndex].Pos.Y) <= RANGO_VISION_Y) { /* ' va hacia el si o esta invi ni oculto */ if (UserList[OwnerIndex].flags.invisible == 0 && UserList[OwnerIndex].flags.Oculto == 0 && !UserList[OwnerIndex].flags.EnConsulta && !UserList[OwnerIndex].flags.Ignorado) { if (Npclist[NpcIndex].flags.LanzaSpells != 0) { NpcLanzaUnSpell(NpcIndex, OwnerIndex); } tHeading = FindDirection(Npclist[NpcIndex].Pos, UserList[OwnerIndex].Pos); MoveNPCChar(NpcIndex, tHeading); return; } } } /* ' Esto significa que esta bugueado.. Lo logueo, y "reparo" el error a mano (Todo temporal) */ } else { LogError( "El npc: " + Npclist[NpcIndex].Name + "(" + std::to_string(NpcIndex) + "), intenta atacar a " + UserList[OwnerIndex].Name + "(Index: " + std::to_string(OwnerIndex) + ", Mapa: " + std::to_string(UserList[OwnerIndex].Pos.Map) + ") desde el mapa " + std::to_string(Npclist[NpcIndex].Pos.Map)); Npclist[NpcIndex].Owner = 0; } } /* ' No le pertenece a nadie o el dueno no esta en el rango de vision, sigue a cualquiera */ for (i = (1); i <= (ConnGroups[Npclist[NpcIndex].Pos.Map].CountEntrys); i++) { UserIndex = ConnGroups[Npclist[NpcIndex].Pos.Map].UserEntrys[i]; /* 'Is it in it's range of vision?? */ if (vb6::Abs(UserList[UserIndex].Pos.X - Npclist[NpcIndex].Pos.X) <= RANGO_VISION_X) { if (vb6::Abs( UserList[UserIndex].Pos.Y - Npclist[NpcIndex].Pos.Y) <= RANGO_VISION_Y) { UserProtected = !IntervaloPermiteSerAtacado(UserIndex) && UserList[UserIndex].flags.NoPuedeSerAtacado; UserProtected = UserProtected || UserList[UserIndex].flags.Ignorado || UserList[UserIndex].flags.EnConsulta; if (UserList[UserIndex].flags.Muerto == 0 && UserList[UserIndex].flags.invisible == 0 && UserList[UserIndex].flags.Oculto == 0 && UserList[UserIndex].flags.AdminPerseguible && !UserProtected) { if (Npclist[NpcIndex].flags.LanzaSpells != 0) { NpcLanzaUnSpell(NpcIndex, UserIndex); } tHeading = FindDirection(Npclist[NpcIndex].Pos, UserList[UserIndex].Pos); MoveNPCChar(NpcIndex, tHeading); return; } } } } /* 'Si llega aca es que no hab�a ning�n usuario cercano vivo. */ /* 'A bailar. Pablo (ToxicWaste) */ if (RandomNumber(0, 10) == 0) { MoveNPCChar(NpcIndex, vb6::CByte(RandomNumber(eHeading_NORTH, eHeading_WEST))); } } RestoreOldMovement(NpcIndex); }