void AceptarComercioUsu(int UserIndex) { /* '*************************************************** */ /* 'Autor: Unkown */ /* 'Last Modification: 06/05/2010 */ /* '25/11/2009: ZaMa - Ahora se traspasan hasta 5 items + oro al comerciar */ /* '06/05/2010: ZaMa - Ahora valida si los usuarios tienen los items que ofertan. */ /* '*************************************************** */ struct Obj TradingObj; int OtroUserIndex; int OfferSlot; UserList[UserIndex].ComUsu.Acepto = true; OtroUserIndex = UserList[UserIndex].ComUsu.DestUsu; /* ' User valido? */ if (OtroUserIndex <= 0 || OtroUserIndex > MaxUsers) { FinComerciarUsu(UserIndex); return; } /* ' Acepto el otro? */ if (UserList[OtroUserIndex].ComUsu.Acepto == false) { return; } /* ' Aceptaron ambos, chequeo que tengan los items que ofertaron */ if (!HasOfferedItems(UserIndex)) { WriteConsoleMsg(UserIndex, "¡¡¡El comercio se canceló porque no posees los ítems que ofertaste!!!", FontTypeNames_FONTTYPE_FIGHT); WriteConsoleMsg(OtroUserIndex, "¡¡¡El comercio se canceló porque " + UserList[UserIndex].Name + " no posee los ítems que ofertó!!!", FontTypeNames_FONTTYPE_FIGHT); FinComerciarUsu(UserIndex); FinComerciarUsu(OtroUserIndex); FlushBuffer(OtroUserIndex); return; } else if (!HasOfferedItems(OtroUserIndex)) { WriteConsoleMsg(UserIndex, "¡¡¡El comercio se canceló porque " + UserList[OtroUserIndex].Name + " no posee los ítems que ofertó!!!", FontTypeNames_FONTTYPE_FIGHT); WriteConsoleMsg(OtroUserIndex, "¡¡¡El comercio se canceló porque no posees los ítems que ofertaste!!!", FontTypeNames_FONTTYPE_FIGHT); FinComerciarUsu(UserIndex); FinComerciarUsu(OtroUserIndex); FlushBuffer(OtroUserIndex); return; } /* ' Envio los items a quien corresponde */ for (OfferSlot = (1); OfferSlot <= (MAX_OFFER_SLOTS + 1); OfferSlot++) { /* ' Items del 1er usuario */ /* ' Le pasa el oro */ if (OfferSlot == GOLD_OFFER_SLOT) { /* ' Quito la cantidad de oro ofrecida */ UserList[UserIndex].Stats.GLD = UserList[UserIndex].Stats.GLD - UserList[UserIndex].ComUsu.GoldAmount; /* ' Log */ if (UserList[UserIndex].ComUsu.GoldAmount >= MIN_GOLD_AMOUNT_LOG) { LogDesarrollo( UserList[UserIndex].Name + " soltó oro en comercio seguro con " + UserList[OtroUserIndex].Name + ". Cantidad: " + vb6::CStr(UserList[UserIndex].ComUsu.GoldAmount)); } /* ' Update Usuario */ WriteUpdateGold(UserIndex); /* ' Se la doy al otro */ UserList[OtroUserIndex].Stats.GLD = UserList[OtroUserIndex].Stats.GLD + UserList[UserIndex].ComUsu.GoldAmount; /* ' Update Otro Usuario */ WriteUpdateGold(OtroUserIndex); /* ' Le pasa lo ofertado de los slots con items */ } else if (UserList[UserIndex].ComUsu.Objeto[OfferSlot] > 0) { TradingObj.ObjIndex = UserList[UserIndex].ComUsu.Objeto[OfferSlot]; TradingObj.Amount = UserList[UserIndex].ComUsu.cant[OfferSlot]; /* 'Quita el objeto y se lo da al otro */ if (!MeterItemEnInventario(OtroUserIndex, TradingObj)) { TirarItemAlPiso(UserList[OtroUserIndex].Pos, TradingObj); } QuitarObjetos(TradingObj.ObjIndex, TradingObj.Amount, UserIndex); /* 'Es un Objeto que tenemos que loguear? Pablo (ToxicWaste) 07/09/07 */ if (((ObjData[TradingObj.ObjIndex].Log == 1) || (ObjData[TradingObj.ObjIndex].OBJType == eOBJType_otLlaves))) { LogDesarrollo( UserList[UserIndex].Name + " le pasó en comercio seguro a " + UserList[OtroUserIndex].Name + " " + vb6::CStr(TradingObj.Amount) + " " + ObjData[TradingObj.ObjIndex].Name); /* 'Es mucha cantidad? */ } else if (TradingObj.Amount >= MIN_AMOUNT_LOG) { /* 'Si no es de los prohibidos de loguear, lo logueamos. */ if (ObjData[TradingObj.ObjIndex].NoLog != 1) { LogDesarrollo( UserList[UserIndex].Name + " le pasó en comercio seguro a " + UserList[OtroUserIndex].Name + " " + vb6::CStr(TradingObj.Amount) + " " + ObjData[TradingObj.ObjIndex].Name); } } else if ((TradingObj.Amount * ObjData[TradingObj.ObjIndex].Valor) >= MIN_VALUE_LOG) { /* 'Si no es de los prohibidos de loguear, lo logueamos. */ if (ObjData[TradingObj.ObjIndex].NoLog != 1) { LogDesarrollo( UserList[UserIndex].Name + " le pasó en comercio seguro a " + UserList[OtroUserIndex].Name + " " + vb6::CStr(TradingObj.Amount) + " " + ObjData[TradingObj.ObjIndex].Name); } } } /* ' Items del 2do usuario */ /* ' Le pasa el oro */ if (OfferSlot == GOLD_OFFER_SLOT) { /* ' Quito la cantidad de oro ofrecida */ UserList[OtroUserIndex].Stats.GLD = UserList[OtroUserIndex].Stats.GLD - UserList[OtroUserIndex].ComUsu.GoldAmount; /* ' Log */ if (UserList[OtroUserIndex].ComUsu.GoldAmount >= MIN_GOLD_AMOUNT_LOG) { LogDesarrollo( UserList[OtroUserIndex].Name + " soltó oro en comercio seguro con " + UserList[UserIndex].Name + ". Cantidad: " + vb6::CStr(UserList[OtroUserIndex].ComUsu.GoldAmount)); } /* ' Update Usuario */ WriteUpdateGold(OtroUserIndex); /* 'y se la doy al otro */ UserList[UserIndex].Stats.GLD = UserList[UserIndex].Stats.GLD + UserList[OtroUserIndex].ComUsu.GoldAmount; /* ' Update Otro Usuario */ WriteUpdateGold(UserIndex); /* ' Le pasa la oferta de los slots con items */ } else if (UserList[OtroUserIndex].ComUsu.Objeto[OfferSlot] > 0) { TradingObj.ObjIndex = UserList[OtroUserIndex].ComUsu.Objeto[OfferSlot]; TradingObj.Amount = UserList[OtroUserIndex].ComUsu.cant[OfferSlot]; /* 'Quita el objeto y se lo da al otro */ if (!MeterItemEnInventario(UserIndex, TradingObj)) { TirarItemAlPiso(UserList[UserIndex].Pos, TradingObj); } QuitarObjetos(TradingObj.ObjIndex, TradingObj.Amount, OtroUserIndex); /* 'Es un Objeto que tenemos que loguear? Pablo (ToxicWaste) 07/09/07 */ if (((ObjData[TradingObj.ObjIndex].Log == 1) || (ObjData[TradingObj.ObjIndex].OBJType == eOBJType_otLlaves))) { LogDesarrollo( UserList[OtroUserIndex].Name + " le pasó en comercio seguro a " + UserList[UserIndex].Name + " " + vb6::CStr(TradingObj.Amount) + " " + ObjData[TradingObj.ObjIndex].Name); /* 'Es mucha cantidad? */ } else if (TradingObj.Amount >= MIN_AMOUNT_LOG) { /* 'Si no es de los prohibidos de loguear, lo logueamos. */ if (ObjData[TradingObj.ObjIndex].NoLog != 1) { LogDesarrollo( UserList[OtroUserIndex].Name + " le pasó en comercio seguro a " + UserList[UserIndex].Name + " " + vb6::CStr(TradingObj.Amount) + " " + ObjData[TradingObj.ObjIndex].Name); } } else if ((TradingObj.Amount * ObjData[TradingObj.ObjIndex].Valor) >= MIN_VALUE_LOG) { /* 'Si no es de los prohibidos de loguear, lo logueamos. */ if (ObjData[TradingObj.ObjIndex].NoLog != 1) { LogDesarrollo( UserList[OtroUserIndex].Name + " le pasó en comercio seguro a " + UserList[UserIndex].Name + " " + vb6::CStr(TradingObj.Amount) + " " + ObjData[TradingObj.ObjIndex].Name); } } } } /* ' End Trade */ FinComerciarUsu(UserIndex); FinComerciarUsu(OtroUserIndex); FlushBuffer(OtroUserIndex); }
void NPC_TIRAR_ITEMS(struct npc & npc, bool IsPretoriano) { /* '*************************************************** */ /* 'Autor: Unknown (orginal version) */ /* 'Last Modification: 28/11/2009 */ /* 'Give away npc's items. */ /* '28/11/2009: ZaMa - Implementado drops complejos */ /* '02/04/2010: ZaMa - Los pretos vuelven a tirar oro. */ /* '10/04/2011: ZaMa - Logueo los objetos logueables dropeados. */ /* '*************************************************** */ int i; struct Obj MiObj; int NroDrop; int Random; int ObjIndex; /* ' Tira todo el inventario */ if (IsPretoriano) { for (i = (1); i <= (MAX_INVENTORY_SLOTS); i++) { if (npc.Invent.Object[i].ObjIndex > 0) { MiObj.Amount = npc.Invent.Object[i].Amount; MiObj.ObjIndex = npc.Invent.Object[i].ObjIndex; TirarItemAlPiso(npc.Pos, MiObj); } } /* ' Dropea oro? */ if (npc.GiveGLD > 0) { TirarOroNpc(npc.GiveGLD, npc.Pos); } return; } Random = RandomNumber(1, 100); /* ' Tiene 10% de prob de no tirar nada */ if (Random <= 90) { NroDrop = 1; if (Random <= 10) { NroDrop = NroDrop + 1; for (i = (1); i <= (3); i++) { /* ' 10% de ir pasando de etapas */ if (RandomNumber(1, 100) <= 10) { NroDrop = NroDrop + 1; } else { break; } } } ObjIndex = npc.Drop[NroDrop].ObjIndex; if (ObjIndex > 0) { if (ObjIndex == iORO) { TirarOroNpc(npc.Drop[NroDrop].Amount, npc.Pos); } else { MiObj.Amount = npc.Drop[NroDrop].Amount; MiObj.ObjIndex = ObjIndex; TirarItemAlPiso(npc.Pos, MiObj); if (ObjData[ObjIndex].Log == 1) { LogDesarrollo( npc.Name + " dropeó " + vb6::CStr(MiObj.Amount) + " " + ObjData[ObjIndex].Name + "[" + vb6::CStr(ObjIndex) + "]"); } } } } }
/* ' @param Cantidad Specifies how many items in that slot are you trying to sell / buy */ void Comercio(eModoComercio Modo, int UserIndex, int NpcIndex, int Slot, int Cantidad) { /* '************************************************* */ /* 'Author: Nacho (Integer) */ /* 'Last modified: 07/06/2010 */ /* '27/07/08 (MarKoxX) | New changes in the way of trading (now when you buy it rounds to ceil and when you sell it rounds to floor) */ /* ' - 06/13/08 (NicoNZ) */ /* '07/06/2010: ZaMa - Los objetos se loguean si superan la cantidad de 1k (antes era solo si eran 1k). */ /* '************************************************* */ int Precio; struct Obj Objeto; if (Cantidad < 1 || Slot < 1) { return; } if (Modo == eModoComercio_Compra) { if (Slot > MAX_INVENTORY_SLOTS) { return; } else if (Cantidad > MAX_INVENTORY_OBJS) { SendData(SendTarget_ToAll, 0, dakara::protocol::server::BuildConsoleMsg( UserList[UserIndex].Name + " ha sido baneado por el sistema anti-cheats.", FontTypeNames_FONTTYPE_FIGHT)); Ban(UserList[UserIndex].Name, "Sistema Anti Cheats", "Intentar hackear el sistema de comercio. Quiso comprar demasiados ítems:" + vb6::CStr(Cantidad)); UserList[UserIndex].flags.Ban = 1; WriteErrorMsg(UserIndex, "Has sido baneado por el Sistema AntiCheat."); FlushBuffer(UserIndex); CloseSocket(UserIndex); return; } else if (!(Npclist[NpcIndex].Invent.Object[Slot].Amount > 0)) { return; } if (Cantidad > Npclist[NpcIndex].Invent.Object[Slot].Amount) { Cantidad = Npclist[UserList[UserIndex].flags.TargetNPC].Invent.Object[Slot].Amount; } Objeto.Amount = Cantidad; Objeto.ObjIndex = Npclist[NpcIndex].Invent.Object[Slot].ObjIndex; /* 'El precio, cuando nos venden algo, lo tenemos que redondear para arriba. */ /* 'Es decir, 1.1 = 2, por lo cual se hace de la siguiente forma Precio = Clng(PrecioFinal + 0.5) Siempre va a darte el proximo numero. O el "Techo" (MarKoxX) */ Precio = vb6::CLng( (ObjData[Npclist[NpcIndex].Invent.Object[Slot].ObjIndex].Valor / Descuento(UserIndex) * Cantidad) + 0.5); if (UserList[UserIndex].Stats.GLD < Precio) { WriteConsoleMsg(UserIndex, "No tienes suficiente dinero.", FontTypeNames_FONTTYPE_INFO); return; } if (MeterItemEnInventario(UserIndex, Objeto) == false) { /* 'Call WriteConsoleMsg(UserIndex, "No puedes cargar mas objetos.", FontTypeNames.FONTTYPE_INFO) */ EnviarNpcInv(UserIndex, UserList[UserIndex].flags.TargetNPC); WriteTradeOK(UserIndex); return; } UserList[UserIndex].Stats.GLD = UserList[UserIndex].Stats.GLD - Precio; QuitarNpcInvItem(UserList[UserIndex].flags.TargetNPC, vb6::CByte(Slot), Cantidad); /* 'Bien, ahora logueo de ser necesario. Pablo (ToxicWaste) 07/09/07 */ /* 'Es un Objeto que tenemos que loguear? */ if (ObjData[Objeto.ObjIndex].Log == 1) { LogDesarrollo( UserList[UserIndex].Name + " compró del NPC " + std::to_string(Objeto.Amount) + " " + ObjData[Objeto.ObjIndex].Name); /* 'Es mucha cantidad? */ } else if (Objeto.Amount >= 1000) { /* 'Si no es de los prohibidos de loguear, lo logueamos. */ if (ObjData[Objeto.ObjIndex].NoLog != 1) { LogDesarrollo( UserList[UserIndex].Name + " compró del NPC " + std::to_string(Objeto.Amount) + " " + ObjData[Objeto.ObjIndex].Name); } } /* 'Agregado para que no se vuelvan a vender las llaves si se recargan los .dat. */ if (ObjData[Objeto.ObjIndex].OBJType == eOBJType_otLlaves) { WriteVar(GetDatPath(DATPATH::NPCs), "NPC" + vb6::CStr(Npclist[NpcIndex].Numero), "obj" + vb6::CStr(Slot), vb6::CStr(Objeto.ObjIndex) + "-0"); logVentaCasa(UserList[UserIndex].Name + " compró " + ObjData[Objeto.ObjIndex].Name); } } else if (Modo == eModoComercio_Venta) { if (Cantidad > UserList[UserIndex].Invent.Object[Slot].Amount) { Cantidad = UserList[UserIndex].Invent.Object[Slot].Amount; } Objeto.Amount = Cantidad; Objeto.ObjIndex = UserList[UserIndex].Invent.Object[Slot].ObjIndex; if (Objeto.ObjIndex == 0) { return; } else if (ObjData[Objeto.ObjIndex].Intransferible == 1 || ObjData[Objeto.ObjIndex].NoComerciable == 1) { WriteConsoleMsg(UserIndex, "No puedes vender este tipo de objeto.", FontTypeNames_FONTTYPE_INFO); return; } else if ((Npclist[NpcIndex].TipoItems != ObjData[Objeto.ObjIndex].OBJType && Npclist[NpcIndex].TipoItems != eOBJType_otCualquiera) || Objeto.ObjIndex == iORO) { WriteConsoleMsg(UserIndex, "Lo siento, no estoy interesado en este tipo de objetos.", FontTypeNames_FONTTYPE_INFO); EnviarNpcInv(UserIndex, UserList[UserIndex].flags.TargetNPC); WriteTradeOK(UserIndex); return; } else if (ObjData[Objeto.ObjIndex].Real == 1) { if (Npclist[NpcIndex].Name != "SR") { WriteConsoleMsg(UserIndex, "Las armaduras del ejército real sólo pueden ser vendidas a los sastres reales.", FontTypeNames_FONTTYPE_INFO); EnviarNpcInv(UserIndex, UserList[UserIndex].flags.TargetNPC); WriteTradeOK(UserIndex); return; } } else if (ObjData[Objeto.ObjIndex].Caos == 1) { if (Npclist[NpcIndex].Name != "SC") { WriteConsoleMsg(UserIndex, "Las armaduras de la legión oscura sólo pueden ser vendidas a los sastres del demonio.", FontTypeNames_FONTTYPE_INFO); EnviarNpcInv(UserIndex, UserList[UserIndex].flags.TargetNPC); WriteTradeOK(UserIndex); return; } } else if (UserList[UserIndex].Invent.Object[Slot].Amount < 0 || Cantidad == 0) { return; } else if (Slot<vb6::LBound(UserList[UserIndex].Invent.Object) || Slot>vb6::UBound(UserList[UserIndex].Invent.Object)) { EnviarNpcInv(UserIndex, UserList[UserIndex].flags.TargetNPC); return; } else if (UserTienePrivilegio(UserIndex, PlayerType_Consejero)) { WriteConsoleMsg(UserIndex, "No puedes vender ítems.", FontTypeNames_FONTTYPE_WARNING); EnviarNpcInv(UserIndex, UserList[UserIndex].flags.TargetNPC); WriteTradeOK(UserIndex); return; } QuitarUserInvItem(UserIndex, Slot, Cantidad); /* 'Precio = Round(ObjData(Objeto.ObjIndex).valor / REDUCTOR_PRECIOVENTA * Cantidad, 0) */ Precio = vb6::Fix(SalePrice(Objeto.ObjIndex) * Cantidad); UserList[UserIndex].Stats.GLD = UserList[UserIndex].Stats.GLD + Precio; if (UserList[UserIndex].Stats.GLD > MAXORO) { UserList[UserIndex].Stats.GLD = MAXORO; } int NpcSlot; NpcSlot = SlotEnNPCInv(NpcIndex, Objeto.ObjIndex, Objeto.Amount); /* 'Slot valido */ if (NpcSlot <= MAX_INVENTORY_SLOTS) { /* 'Mete el obj en el slot */ Npclist[NpcIndex].Invent.Object[NpcSlot].ObjIndex = Objeto.ObjIndex; Npclist[NpcIndex].Invent.Object[NpcSlot].Amount = Npclist[NpcIndex].Invent.Object[NpcSlot].Amount + Objeto.Amount; if (Npclist[NpcIndex].Invent.Object[NpcSlot].Amount > MAX_INVENTORY_OBJS) { Npclist[NpcIndex].Invent.Object[NpcSlot].Amount = MAX_INVENTORY_OBJS; } } /* 'Bien, ahora logueo de ser necesario. Pablo (ToxicWaste) 07/09/07 */ /* 'Es un Objeto que tenemos que loguear? */ if (ObjData[Objeto.ObjIndex].Log == 1) { LogDesarrollo( UserList[UserIndex].Name + " vendió al NPC " + std::to_string(Objeto.Amount) + " " + ObjData[Objeto.ObjIndex].Name); /* 'Es mucha cantidad? */ } else if (Objeto.Amount >= 1000) { /* 'Si no es de los prohibidos de loguear, lo logueamos. */ if (ObjData[Objeto.ObjIndex].NoLog != 1) { LogDesarrollo( UserList[UserIndex].Name + " vendió al NPC " + std::to_string(Objeto.Amount) + " " + ObjData[Objeto.ObjIndex].Name); } } } UpdateUserInv(true, UserIndex, 0); WriteUpdateUserStats(UserIndex); EnviarNpcInv(UserIndex, UserList[UserIndex].flags.TargetNPC); WriteTradeOK(UserIndex); SubirSkill(UserIndex, eSkill_Comerciar, true); }