RevScript TFS 1.X VIP System

Alex

Miembro del equipo
Webdesigner
LV
58
 
Awards
38
VIP System TFS 1.0, 1.1 y 1.2, no testeado en 1.3, pero debería de funcionar.
Sistema creado por The Forgotten Server.

Primeramente nos iremos a nuestra base de datos en phpMyAdmin, arriba le daremos ejecutar SQL:

ALTER TABLE `accounts`
ADD COLUMN `viplastday` int(10) NOT NULL DEFAULT 0 AFTER `lastday`,
ADD COLUMN `vipdays` int(11) NOT NULL DEFAULT 0 AFTER `lastday`;

Luego iremos en data/scripts/creaturescripts/others/login.lua , después de function playerLogin.onLogin(player) añadiremos:
player:loadVipData()
player:updateVipTime()
Nos iremos en data/global.lua o data/lib/lib.lua , digo global.lua o Lib.lua, porqué en el global.lua, esta agregado el dofile lib.lua y carga también ahi las lineas, entonces es la misma cosa.

-- Vip System
dofile('data/scripts/vip/vip-system.lua')
Vamos en en data/scripts/ crearemos una carpeta llamada vip y le pondremos un archivo .lua dentro llamado vip-system.lua:
local config = {
-- true = player will be teleported to this position if Vip runs out
-- false = player will not be teleported
useTeleport = true,
expirationPosition = Position(95, 114, 7),

-- true = player will received the message you set
-- false = player will not receive a message
useMessage = true,
expirationMessage = 'Your vip days ran out.',
expirationMessageType = MESSAGE_STATUS_WARNING
}

if not VipData then
VipData = { }
end

function Player.onRemoveVip(self)
if config.useTeleport then
self:teleportTo(config.expirationPosition)
config.expirationPosition:sendMagicEffect(CONST_ME_TELEPORT)
end

if config.useMessage then
self:sendTextMessage(config.expirationMessageType, config.expirationMessage)
end
end

function Player.getVipDays(self)
return VipData[self:getId()].days
end

function Player.getLastVipDay(self)
return VipData[self:getId()].lastDay
end

function Player.isVip(self)
return self:getVipDays() > 0
end

function Player.addInfiniteVip(self)
local data = VipData[self:getId()]
data.days = 0xFFFF
data.lastDay = 0

db.query(string.format('UPDATE `accounts` SET `vipdays` = %i, `viplastday` = %i WHERE `id` = %i;', 0xFFFF, 0, self:getAccountId()))
end

function Player.addVipDays(self, amount)
local data = VipData[self:getId()]
local amount = math.min(0xFFFE - data.days, amount)
if amount > 0 then
if data.days == 0 then
local time = os.time()
db.query(string.format('UPDATE `accounts` SET `vipdays` = `vipdays` + %i, `viplastday` = %i WHERE `id` = %i;', amount, time, self:getAccountId()))
data.lastDay = time
else
db.query(string.format('UPDATE `accounts` SET `vipdays` = `vipdays` + %i WHERE `id` = %i;', amount, self:getAccountId()))
end
data.days = data.days + amount
end

return true
end

function Player.removeVipDays(self, amount)
local data = VipData[self:getId()]
if data.days == 0xFFFF then
return false
end

local amount = math.min(data.days, amount)
if amount > 0 then
db.query(string.format('UPDATE `accounts` SET `vipdays` = `vipdays` - %i WHERE `id` = %i;', amount, self:getAccountId()))
data.days = data.days - amount

if data.days == 0 then
self:eek:nRemoveVip()
end
end

return true
end

function Player.removeVip(self)
local data = VipData[self:getId()]
if data.days == 0 then
return
end

data.days = 0
data.lastDay = 0

self:OnRemoveVip()

db.query(string.format('UPDATE `accounts` SET `vipdays` = 0, `viplastday` = 0 WHERE `id` = %i;', self:getAccountId()))
end

function Player.loadVipData(self)
local resultId = db.storeQuery(string.format('SELECT `vipdays`, `viplastday` FROM `accounts` WHERE `id` = %i;', self:getAccountId()))
if resultId then
VipData[self:getId()] = {
days = result.getDataInt(resultId, 'vipdays'),
lastDay = result.getDataInt(resultId, 'viplastday')
}

result.free(resultId)
return true
end

VipData[self:getId()] = { days = 0, lastDay = 0 }
return false
end

function Player.updateVipTime(self)
local save = false

local data = VipData[self:getId()]
local days, lastDay = data.days, data.lastDay
local daysBefore = days
if days == 0 or days == 0xFFFF then
if lastDay ~= 0 then
lastDay = 0
save = true
end
elseif lastDay == 0 then
lastDay = os.time()
save = true
else
local time = os.time()
local elapsedDays = math.floor((time - lastDay) / 86400)
if elapsedDays > 0 then
if elapsedDays >= days then
days = 0
lastDay = 0
else
days = days - elapsedDays
lastDay = time - ((time - lastDay) % 86400)
end
save = true
end
end

if save then
if daysBefore > 0 and days == 0 then
self:OnRemoveVip()
end

db.query(string.format('UPDATE `accounts` SET `vipdays` = %i, `viplastday` = %i WHERE `id` = %i;', days, lastDay, self:getAccountId()))
data.days = days
data.lastDay = lastDay
end
end

Hasta aqui, se termina el sistema VIP, ahora veremos para incorporar TalkAction , Puertas y Acessos:

TalkAction !checkvip ( Players )
Este comando es para verificar los días de VIP que quedan.
Iremos en data/scripts/talkaction/player/ y crearemos un archivo llamado checkvip.lua:

local checkVip = TalkAction("!checkvip")

function checkVip.onSay(cid, words, param)
local player = Player(cid)

local days = player:getVipDays()
if days == 0 then
player:sendCancelMessage('You do not have any vip days.')
else
player:sendCancelMessage(string.format('You have %s vip day%s left.', (days == 0xFFFF and 'infinite amount of' or days), (days == 1 and '' or 's')))
end
return false
end

checkVip:separator(" ")
checkVip:register()

TalkAction /vip para los GM/GOD:

/vip adddays, PlayerName, 5

Añade 5 Dias VIP al jugador
/vip removedays, PlayerName, 5
Quita 5 Dias VIP al jugador
/vip remove, PlayerName
Quita todos los dias VIP a un jugador
/vip check, PlayerName
Verifica los días VIP que tiene el jugador
/vip addinfinite, PlayerName
Anade VIP infinito al jugador

Nos iremos en data/scripts/talkaction/god/ y crearemos un archivo llamado vipcommand.lua

local vipMod = TalkAction("/vip")


function vipMod.onSay(cid, words, param)
local player = Player(cid)
if not player:getGroup():getAccess() then
return true
end

local params = param:split(',')
if not params[2] then
player:sendTextMessage(MESSAGE_INFO_DESCR, string.format('Player is required.\nUsage:\n%s <action>, <name>, [, <value>]\n\nAvailable actions:\ncheck, adddays, addinfinite, removedays, remove', words))
return false
end

local targetName = params[2]:trim()
local target = Player(targetName)
if not target then
player:sendCancelMessage(string.format('Player (%s) is not online. Usage: %s <action>, <player> [, <value>]', targetName, words))
return false
end

local action = params[1]:trim():lower()
if action == 'adddays' then
local amount = tonumber(params[3])
if not amount then
player:sendCancelMessage('<value> has to be a numeric value.')
return false
end

target:addVipDays(amount)
player:sendCancelMessage(string.format('%s received %s vip day(s) and now has %s vip day(s).', target:getName(), amount, target:getVipDays()))

elseif action == 'removedays' then
local amount = tonumber(params[3])
if not amount then
player:sendCancelMessage('<value> has to be a numeric value.')
return false
end

target:removeVipDays(amount)
player:sendCancelMessage(string.format('%s lost %s vip day(s) and now has %s vip day(s).', target:getName(), amount, target:getVipDays()))

elseif action == 'addinfinite' then
target:addInfiniteVip()
player:sendCancelMessage(string.format('%s now has infinite vip time.', target:getName()))

elseif action == 'remove' then
target:removeVip()
player:sendCancelMessage(string.format('You removed all vip days from %s.', target:getName()))

elseif action == 'check' then
local days = target:getVipDays()
player:sendCancelMessage(string.format('%s has %s vip day(s).', target:getName(), (days == 0xFFFF and 'infinite' or days)))

else
player:sendTextMessage(MESSAGE_INFO_DESCR, string.format('Action is required.\nUsage:\n%s <action>, <name>, [, <value>]\n\nAvailable actions:\ncheck, adddays, addinfinite, removedays, remove', words))
end
return false
end

vipMod:separator(" ")
vipMod:register()

Tiles para los VIP
( suelos ) en lo cual dejara o no dejara pasar a un jugador ( VIP o no ):

Tile 1500: No dejara pasar a los players que no son VIP.
Tile 1501: Hara TP a los players vip a una posicion.

Deberás de modificar la posición en este script, en cuando uses la ActionID 1501 en un suelo para que los Players VIP sean teleportados, deberás de modificar la posición 101,116,7 de este script, para ir por ejemplo en una isla o el sitio que sea VIP en tu servidor.

local vipTile = MoveEvent()
local vipPosition = Position(101, 116, 7)

function vipTile.onStepIn(cid, item, position, fromPosition)
local player = Player(cid)
if not player then
return true
end

if item.actionid == 1500 then
if not player:isVip() then
player:teleportTo(fromPosition)
fromPosition:sendMagicEffect(CONST_ME_POFF)
player:sendCancelMessage('You do not have any vip days.')
end
elseif item.actionid == 1501 then
if player:isVip() then
player:teleportTo(vipPosition)
player:say('!* VIP *!', TALKTYPE_MONSTER_SAY)
vipPosition:sendMagicEffect(CONST_ME_STUN)
else
player:teleportTo(fromPosition)
player:sendCancelMessage('You do not have any vip days.')
fromPosition:sendMagicEffect(CONST_ME_POFF)
end
end
return true
end
vipTile:type("stepin")
vipTile:aid(1500,1501)
vipTile:register()

Si no funciona este RevScript, podemos referirnos al Script del premium bridge de rookgard, que tiene el mismo sistema:
Basta en cambiar todo lo que dice
"if player:isPremium()" en "ifplayer:isVip()"
obviamente el local failPosition =, cambiar la posicion
debajo el local premiumBridge, por otro nombre , ejemplo vipBridge
Al final del RevScript, cambiar la aid , por la 1501 que seria la AID que dejaria pasar al jugador.

local failPosition = Position(32066, 32192, 7)

local premiumBridge = MoveEvent()

function premiumBridge.onStepIn(creature, item, position, fromPosition)
local player = creature:getPlayer()
if not player then
return true
end

if player:isPremium() then
return true
end

failPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE)
player:teleportTo(failPosition)
return true
end

premiumBridge:type("stepin")
premiumBridge:aid(50241)
premiumBridge:register()

Puertas VIP
Hay 3 versiones de puertas
AID 1502 , puerta mirando hacia abajo, teleporta al player de abajo para arriba
AID 1503, puerta mirando al lado, teleporta de la izquierda a la derecha
AID 1504, da teleport a una posición que indicaste al Script

Nos vamos en data/scripts/actions y creamos un archivo llamado vipdoors.lua

local vipDoor = Action()
local vipPosition = Position(101, 116, 7)

function vipDoor.onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)
local player = Player(cid)
if item.actionid == 1502 then
local position = player:getPosition()
if position.y < fromPosition.y then
fromPosition.y = fromPosition.y + 1
else
fromPosition.y = fromPosition.y - 1
end
player:teleportTo(fromPosition)
player:say('!* VIP *!', TALKTYPE_MONSTER_SAY)
fromPosition:sendMagicEffect(CONST_ME_STUN)

elseif item.actionid == 1503 then
local position = player:getPosition()
if position.x < fromPosition.x then
fromPosition.x = fromPosition.x + 1
else
fromPosition.x = fromPosition.x - 1
end
player:teleportTo(fromPosition)
player:say('!* VIP *!', TALKTYPE_MONSTER_SAY)
fromPosition:sendMagicEffect(CONST_ME_STUN)

elseif item.actionid == 1504 then
if player:isVip() then
player:teleportTo(vipPosition)
player:say('!* VIP *!', TALKTYPE_MONSTER_SAY)
vipPosition:sendMagicEffect(CONST_ME_STUN)
else
player:sendCancelMessage('You do not have any vip days.')
end
end
return true
end


vipDoor:id(1502, 1503, 1504)
vipDoor:register()

Items VIP que dan dias de VIP

Eligiran Items ID de su servidor ( que no se puedan obtener y que quieran poner en su webshop o en la tienda por tibiacoins ):

Nos iremos en data/scripts/actions y crearemos un archivo llamado vipitems.lua
Cada [ITEMID] o ITEMID, le pondran la ITEMID que han elegido, se han puesto 3 pero se pueden poner mas, con comas y siguiendo el script:
local vipAdd = Action()
local vipItems = {
-- [itemid] = amount of vip days
[ITEMID] = 10,
[ITEMID] = 30,
[ITEMID] = 90
}

function vipAdd.onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)
local player = Player(cid)
local days = vipItems[item.itemid]
player:addVipDays(days)
player:say('!* YAY VIP! *!', TALKTYPE_MONSTER_SAY)
player:getPosition():sendMagicEffect(CONST_ME_STUN)
player:sendTextMessage(MESSAGE_INFO_DESCR, string.format('You received %s vip days.', days))
Item(item.uid):remove(1)
return true
end

vipAdd:id(ITEMID, ITEMID, ITEMID)
vipAdd:register()
 
Última edición:
Y

yosoyjuanx

Invitado
Hola hay forma de hacer que los player vips tengan un poco mas de experiencia al ser vips.
 

Alex

Miembro del equipo
Webdesigner
LV
58
 
Awards
38
Hola hay forma de hacer que los player vips tengan un poco mas de experiencia al ser vips.
Hola,
Seguramente que sí, habría que encontrar un script, convertirlo y agregarlo al servidor incluyendo que si es VIP ganaría exp x2 por ejemplo o +10%.
No soy scripter no sabría montarlo.
 

GOD Vader

Miembro
LV
16
 
Awards
14
Todo perfecto, pero hay alguna forma de agregar esto a la Store y que de el vip de forma automática y los días comprados ? por ej reemplazar el premium time por el Vip dentro de la store
 

Alex

Miembro del equipo
Webdesigner
LV
58
 
Awards
38
Todo perfecto, pero hay alguna forma de agregar esto a la Store y que de el vip de forma automática y los días comprados ? por ej reemplazar el premium time por el Vip dentro de la store
Items que dan VIP, si , el último script lo dice, en ese caso ese item se agrega al store/webstore. Reemplazar el VIP por el premium significa remplazar sources , premium es algo que viene por defecto y modificado en sources, para verlo un poco,
Descárgate Visual Studio Code, abre la carpeta entera de tu OT en el Visual Studio Code y busca premium, verás que sale en muchos archivos, habría que cambiar en cada archivo y en sources y/o otros archivos indicar y cambiar las id del premium en el store por VIP items en ese caso o agregar nuevas id.
No sabría cómo hacerlo, pero seguramente es esto, lo poco que he probado por deducción ( crear nueva categoría bestiary, nueva vocation ) en 12x le ha funcionado perfectamente, pero, modificando sources y compilando.
 

GOD Vader

Miembro
LV
16
 
Awards
14
Items que dan VIP, si , el último script lo dice, en ese caso ese item se agrega al store/webstore. Reemplazar el VIP por el premium significa remplazar sources , premium es algo que viene por defecto y modificado en sources, para verlo un poco,
Descárgate Visual Studio Code, abre la carpeta entera de tu OT en el Visual Studio Code y busca premium, verás que sale en muchos archivos, habría que cambiar en cada archivo y en sources y/o otros archivos indicar y cambiar las id del premium en el store por VIP items en ese caso o agregar nuevas id.
No sabría cómo hacerlo, pero seguramente es esto, lo poco que he probado por deducción ( crear nueva categoría bestiary, nueva vocation ) en 12x le ha funcionado perfectamente, pero, modificando sources y compilando.
Lo voy a intentar de esa forma 😁(y)

lo otro, tengo un problema con el código, me está lanzando el siguiente error:

https://prnt.sc/5mJTOfiOjoEs

todo después de ingresar los scripts de vip 😓
 

Alex

Miembro del equipo
Webdesigner
LV
58
 
Awards
38

Alex

Miembro del equipo
Webdesigner
LV
58
 
Awards
38

sbslobo

Miembro
LV
1
 
Awards
3
Hola, me encantó tu script por completo y agradezco mucho que lo hayas compartido!

Por mi cuenta yo agregué en Login.lua comandos para que el jugador vip reciba monturas y un item la primera vez que compra y aquí encontré un pequeño error en donde tu colocas las lineas:

player:loadVipData()

player:updateVipTime()

Esto genera un error ya que las colocas en la línea dos de login.lua y esta linea pertenece a la funcion
local function onMovementRemoveProtection(cid, oldPos, time)
cuando debería estar dentro de la funcion
function playerLogin.onLogin(player)

ya que al no ser así, en algunos casos manda que la funcion function Player.getVipDays(self) dentro de vip-system arroje un valor nulo al primer login del player.

Espero haberme dado a entender.

Saludos! y de nuevo agradezco tu script
 

Alex

Miembro del equipo
Webdesigner
LV
58
 
Awards
38
Hola, me encantó tu script por completo y agradezco mucho que lo hayas compartido!

Por mi cuenta yo agregué en Login.lua comandos para que el jugador vip reciba monturas y un item la primera vez que compra y aquí encontré un pequeño error en donde tu colocas las lineas:

player:loadVipData()
player:updateVipTime()

Esto genera un error ya que las colocas en la línea dos de login.lua y esta linea pertenece a la funcion
local function onMovementRemoveProtection(cid, oldPos, time)
cuando debería estar dentro de la funcion
function playerLogin.onLogin(player)

ya que al no ser así, en algunos casos manda que la funcion function Player.getVipDays(self) dentro de vip-system arroje un valor nulo al primer login del player.

Espero haberme dado a entender.

Saludos! y de nuevo agradezco tu script
Hola,

Exacto, fué creado y hecho para un servidor utilizando functions differentes y se me olvido cambiar el método de registro, que al igual que agregar ya sea un evento o una quest al player se pone debajo de la function onLogin.
 

GOD Vader

Miembro
LV
16
 
Awards
14
Consulta, esto funcionaría para servidor 13x ?
Hola, me encantó tu script por completo y agradezco mucho que lo hayas compartido!

Por mi cuenta yo agregué en Login.lua comandos para que el jugador vip reciba monturas y un item la primera vez que compra y aquí encontré un pequeño error en donde tu colocas las lineas:

player:loadVipData()
player:updateVipTime()

Esto genera un error ya que las colocas en la línea dos de login.lua y esta linea pertenece a la funcion
local function onMovementRemoveProtection(cid, oldPos, time)
cuando debería estar dentro de la funcion
function playerLogin.onLogin(player)

ya que al no ser así, en algunos casos manda que la funcion function Player.getVipDays(self) dentro de vip-system arroje un valor nulo al primer login del player.

Espero haberme dado a entender.

Saludos! y de nuevo agradezco tu script
y como sería esta modificación ?
 
Arriba