/* 'destino: receptor de la transaccion */
void IniciarComercioConUsuario(int Origen, int Destino) {
	/* '*************************************************** */
	/* 'Autor: Unkown */
	/* 'Last Modification: 25/11/2009 */
	/* ' */
	/* '*************************************************** */

	/* 'Si ambos pusieron /comerciar entonces */
	if (UserList[Origen].ComUsu.DestUsu == Destino && UserList[Destino].ComUsu.DestUsu == Origen) {

		if (UserList[Origen].flags.Comerciando || UserList[Destino].flags.Comerciando) {
			WriteConsoleMsg(Origen, "No puedes comerciar en este momento", FontTypeNames_FONTTYPE_TALK);
			WriteConsoleMsg(Destino, "No puedes comerciar en este momento", FontTypeNames_FONTTYPE_TALK);
			return;
		}

		/* 'Actualiza el inventario del usuario */
		UpdateUserInv(true, Origen, 0);
		/* 'Decirle al origen que abra la ventanita. */
		WriteUserCommerceInit(Origen);
		UserList[Origen].flags.Comerciando = true;

		/* 'Actualiza el inventario del usuario */
		UpdateUserInv(true, Destino, 0);
		/* 'Decirle al origen que abra la ventanita. */
		WriteUserCommerceInit(Destino);
		UserList[Destino].flags.Comerciando = true;

		/* 'Call EnviarObjetoTransaccion(Origen) */
	} else {
		/* 'Es el primero que comercia ? */
		WriteConsoleMsg(Destino,
				UserList[Origen].Name + " desea comerciar. Si deseas aceptar, escribe /COMERCIAR.",
				FontTypeNames_FONTTYPE_TALK);
		UserList[Destino].flags.TargetUser = Origen;

	}

	FlushBuffer(Destino);
}
Beispiel #2
0
/* ' @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);
}