• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

TFS 1.X+ Looktype Bug's [tfs 1.2]

Pifafa

Active Member
Joined
Nov 9, 2010
Messages
100
Reaction score
39
Hello friends, I come today to ask everyone for help, when trying to use looktype, they simply turn others wrong, I can't understand the cause of the problem at all.

1738004027406.webp

example, when trying to use the command for a /looktype 297 instead of turning what is in 297 will I turn into a lion?

1738004087835.webp

There seems to be a limitation so that I can put these clothes into the game, I want the person to use x item and get x outfit, in fact token just for him to transform into that for some time.

I'm going to leave my GM looktype script and the script I made as an action.


ADM:

LUA:
function onSay(player, words, param)
    -- Verifica se o jogador é um administrador
    if player:getGroup():getAccess() then
        local lookType = tonumber(param)
        if lookType and lookType >= 0 then
            local playerOutfit = player:getOutfit()
            playerOutfit.lookType = lookType
            player:setOutfit(playerOutfit)
        else
            player:sendCancelMessage("Invalid look type.")
        end
    else
        -- Caso o jogador não seja admin, verifica a lista de lookTypes permitidos
        local lookType = tonumber(param)
        if (lookType >= 0 and lookType ~= 1 and lookType ~= 135 and lookType ~= 411 and lookType ~= 415 and lookType ~= 424
            and (lookType <= 160 or lookType >= 192) and lookType ~= 439 and lookType ~= 440 and lookType ~= 468 and lookType ~= 469
            and (lookType < 474 or lookType > 485) and lookType ~= 501 and lookType ~= 518 and lookType ~= 519 and lookType ~= 520
            and lookType ~= 524 and lookType ~= 525 and lookType ~= 536 and lookType ~= 543 and lookType ~= 549 and lookType ~= 576
            and lookType ~= 581 and lookType ~= 582 and lookType ~= 597 and lookType ~= 616 and lookType ~= 623 and lookType ~= 625
            and (lookType <= 637 or lookType >= 644) and (lookType <= 644 or lookType >= 647) and (lookType <= 651 or lookType >= 664)
            and lookType <= 699) or (lookType >= 161 and lookType <= 193) then
            local playerOutfit = player:getOutfit()
            playerOutfit.lookType = lookType
            player:setOutfit(playerOutfit)
        else
            player:sendCancelMessage("A look type with that id does not exist.")
        end
    end
    return false
end


Player action:

LUA:
-- Item Script for Outfit Changer
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local maleOutfitID = 513 -- Outfit ID para sexo masculino
    local femaleOutfitID = 184 -- Outfit ID para sexo feminino
    local universalOutfitID = 513 -- Outfit ID universal para ambos os sexos

    -- Define a lista de opções possíveis de outfits
    local outfitOptions = {maleOutfitID, femaleOutfitID, universalOutfitID}

    -- Escolhe um outfit aleatoriamente
    local randomIndex = math.random(#outfitOptions)
    local selectedOutfitID = outfitOptions[randomIndex]

    -- Verifica o sexo do jogador para aplicar a lógica correta
    local outfitID
    if selectedOutfitID == maleOutfitID or selectedOutfitID == femaleOutfitID then
        outfitID = player:getSex() == PLAYERSEX_MALE and maleOutfitID or femaleOutfitID
    else
        outfitID = universalOutfitID
    end

    -- Aplica o outfit ao jogador
    local playerOutfit = player:getOutfit()
    playerOutfit.lookType = outfitID
    player:setOutfit(playerOutfit)

    -- Adiciona efeito visual e mensagem
    player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
    player:sendTextMessage(MESSAGE_INFO_DESCR, "Your outfit has been randomly changed!")

    -- Remove 1 unidade do item após o uso
    item:remove(1)
    return true
end
 
I created two scripts, but after reading some messages, I'm not entirely sure what you want: a click that gives a random outfit or a fixed outfit for a while that reverts to the original later. So, I made both options, and you can test them out!

random outfit.
LUA:
local config = {
    durationSeconds = 60,  -- Duration of the outfit effect in seconds (1 minute)
    storageValue = 4512,   -- Storage value to track if the effect is active
    effect = CONST_ME_MAGIC_BLUE, -- Visual effect
    outfits = {
        male = {128, 129, 130, 131, 132, 133},
        female = {136, 137, 138, 139, 140, 141, 142, 147}
    }
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local _player = Player(item:getTopParent())
    if not player or player:getId() ~= player:getId() then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "You cannot use this item on the ground. Only in backpack.")
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return true
    end

    local storedTime = player:getStorageValue(config.storageValue)
    local currentTime = os.time()
  
    if storedTime ~= -1 and storedTime > currentTime then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have already activated this effect. Please wait until it expires.")
        return false
    end

    local outfitList = player:getSex() == PLAYERSEX_MALE and config.outfits.male or config.outfits.female
    local randomIndex = math.random(#outfitList)
    local selectedOutfitID = outfitList[randomIndex]

    local currentOutfit = player:getOutfit()
    player:setStorageValue(config.storageValue .. "_outfit", currentOutfit.lookType)
    local outfitCondition = Condition(CONDITION_OUTFIT)
    outfitCondition:setParameter(CONDITION_PARAM_TICKS, config.durationSeconds * 1000)
    outfitCondition:setOutfit({
        lookType = selectedOutfitID,
        lookHead = currentOutfit.lookHead,
        lookBody = currentOutfit.lookBody,
        lookLegs = currentOutfit.lookLegs,
        lookFeet = currentOutfit.lookFeet,
        lookAddons = currentOutfit.lookAddons
    })
  
    player:addCondition(outfitCondition)
  
    player:getPosition():sendMagicEffect(config.effect)
    player:sendTextMessage(MESSAGE_INFO_DESCR, "Your outfit has been randomly changed!")
  
    player:setStorageValue(config.storageValue, currentTime + config.durationSeconds)
  
    addEvent(function(playerGuid)
        local restoredPlayer = Player(playerGuid)
        if restoredPlayer then
            restoredPlayer:removeCondition(CONDITION_OUTFIT)
            local originalOutfit = restoredPlayer:getStorageValue(config.storageValue .. "_outfit")
            if originalOutfit and originalOutfit > 0 then
                local currentColors = restoredPlayer:getOutfit()
                restoredPlayer:setOutfit({
                    lookType = originalOutfit,
                    lookHead = currentColors.lookHead,
                    lookBody = currentColors.lookBody,
                    lookLegs = currentColors.lookLegs,
                    lookFeet = currentColors.lookFeet,
                    lookAddons = currentColors.lookAddons
                })
            end
            restoredPlayer:setStorageValue(config.storageValue, -1)
            restoredPlayer:sendTextMessage(MESSAGE_INFO_DESCR, "Your outfit has been restored.")
        end
    end, config.durationSeconds * 1000, player:getGuid())
  
    item:remove(1)
    return true
end

fixed outfit.
LUA:
local config = {
    durationSeconds = 60,  -- Duration of the outfit effect in seconds (1 minute)
    storageValue = 4512,   -- Storage value to track if the effect is active
    effect = CONST_ME_MAGIC_BLUE, -- Visual effect
    outfits = {
        male = 513,    -- Male outfit ID
        female = 184   -- Female outfit ID
    }
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local _player = Player(item:getTopParent())
    if not player or player:getId() ~= player:getId() then
       player:sendTextMessage(MESSAGE_STATUS_SMALL, "You cannot use this item on the ground. Only in backpack.")
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return true
    end

    local storedTime = player:getStorageValue(config.storageValue)
    local currentTime = os.time()
  
    if storedTime ~= -1 and storedTime > currentTime then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have already activated this effect. Please wait until it expires.")
        return false
    end

    local outfitId = player:getSex() == PLAYERSEX_MALE and config.outfits.male or config.outfits.female
    local currentOutfit = player:getOutfit()
    player:setStorageValue(config.storageValue .. "_outfit", currentOutfit.lookType)
  
    local outfitCondition = Condition(CONDITION_OUTFIT)
    outfitCondition:setParameter(CONDITION_PARAM_TICKS, config.durationSeconds * 1000)
    outfitCondition:setOutfit({
        lookType = outfitId,
        lookHead = currentOutfit.lookHead,
        lookBody = currentOutfit.lookBody,
        lookLegs = currentOutfit.lookLegs,
        lookFeet = currentOutfit.lookFeet,
        lookAddons = currentOutfit.lookAddons
    })
  
    player:addCondition(outfitCondition)
  
    player:getPosition():sendMagicEffect(config.effect)
    player:sendTextMessage(MESSAGE_INFO_DESCR, "Your outfit has been changed!")
  
    player:setStorageValue(config.storageValue, currentTime + config.durationSeconds)
  
    addEvent(function(playerGuid)
        local restoredPlayer = Player(playerGuid)
        if restoredPlayer then
            restoredPlayer:removeCondition(CONDITION_OUTFIT)
            local originalOutfit = restoredPlayer:getStorageValue(config.storageValue .. "_outfit")
            if originalOutfit and originalOutfit > 0 then
                local currentColors = restoredPlayer:getOutfit()
                restoredPlayer:setOutfit({
                    lookType = originalOutfit,
                    lookHead = currentColors.lookHead,
                    lookBody = currentColors.lookBody,
                    lookLegs = currentColors.lookLegs,
                    lookFeet = currentColors.lookFeet,
                    lookAddons = currentColors.lookAddons
                })
            end
            restoredPlayer:setStorageValue(config.storageValue, -1)
            restoredPlayer:sendTextMessage(MESSAGE_INFO_DESCR, "Your outfit has been restored.")
        end
    end, config.durationSeconds * 1000, player:getGuid())
  
    item:remove(1)
    return true
end
 
Last edited:
The script above works, but it doesn't change the doll's loottype, leaving it blank in case it has no clothes on, I believe it's a problem with the src
 
Last edited:
unfortunately it doesn't work, it seems to be something in sourcere.
give a try to edit in database looktype to 297 (just to confirm thats server limitation, it can be any character [make sure its logged of due of edits in database], as i know tfs 1.2
returns looktype 65535 as maximum (its 16_t) not 8_t (where maximum its 250)

anyway, its for original 1.2, server that you choosen can have some modifications, so as you noticed, you can try to look at your source for values like

uint8_t lookType;

in general, check main functions that reading / sending outfit things, that limit for outfits its strange, it exsists as default but for MagicEffects which is default set as maximum 255 (8_t type)
 
give a try to edit in database looktype to 297 (just to confirm thats server limitation, it can be any character [make sure its logged of due of edits in database], as i know tfs 1.2
returns looktype 65535 as maximum (its 16_t) not 8_t (where maximum its 250)

anyway, its for original 1.2, server that you choosen can have some modifications, so as you noticed, you can try to look at your source for values like

uint8_t lookType;

in general, check main functions that reading / sending outfit things, that limit for outfits its strange, it exsists as default but for MagicEffects which is default set as maximum 255 (8_t type)
Hello
1738090588634.webp
When done directly in the server database it took on a new outfit as you predicted.
1738090684045.webp1738090714811.webp


Maybe you would have to create a script that changes the clothes directly in the database?
 
can you upload your luascript.cpp? maybe here is limitation straight in function about setOutfit and set outfit condition.
 
LUA:
int LuaScriptInterface::luaConditionSetOutfit(lua_State* L)

replace this func to this:

LUA:
int LuaScriptInterface::luaConditionSetOutfit(lua_State* L)
{
    // condition:setOutfit(outfit)
    // condition:setOutfit(lookTypeEx, lookType, lookHead, lookBody, lookLegs, lookFeet)
    Outfit_t outfit;
    if (isTable(L, 2)) {
        outfit = getOutfit(L, 2);
    } else {
        outfit.lookFeet = getNumber<uint8_t>(L, 7);
        outfit.lookLegs = getNumber<uint8_t>(L, 6);
        outfit.lookBody = getNumber<uint8_t>(L, 5);
        outfit.lookHead = getNumber<uint8_t>(L, 4);
        outfit.lookType = getNumber<uint16_t>(L, 3);
        outfit.lookTypeEx = getNumber<uint16_t>(L, 2);
    }

    ConditionOutfit* condition = dynamic_cast<ConditionOutfit*>(getUserdata<Condition>(L, 1));
    if (condition) {
        condition->setOutfit(outfit);
        pushBoolean(L, true);
    } else {
        lua_pushnil(L);
    }
    return 1;
}
 
LUA:
int LuaScriptInterface::luaConditionSetOutfit(lua_State* L)

replace this func to this:

LUA:
int LuaScriptInterface::luaConditionSetOutfit(lua_State* L)
{
    // condition:setOutfit(outfit)
    // condition:setOutfit(lookTypeEx, lookType, lookHead, lookBody, lookLegs, lookFeet)
    Outfit_t outfit;
    if (isTable(L, 2)) {
        outfit = getOutfit(L, 2);
    } else {
        outfit.lookFeet = getNumber<uint8_t>(L, 7);
        outfit.lookLegs = getNumber<uint8_t>(L, 6);
        outfit.lookBody = getNumber<uint8_t>(L, 5);
        outfit.lookHead = getNumber<uint8_t>(L, 4);
        outfit.lookType = getNumber<uint16_t>(L, 3);
        outfit.lookTypeEx = getNumber<uint16_t>(L, 2);
    }

    ConditionOutfit* condition = dynamic_cast<ConditionOutfit*>(getUserdata<Condition>(L, 1));
    if (condition) {
        condition->setOutfit(outfit);
        pushBoolean(L, true);
    } else {
        lua_pushnil(L);
    }
    return 1;
}
I made the change and no error appears, but even trying to change the outfit via action nothing happens, it doesn't pick up larger numbers.

script using:

LUA:
-- Item Script for Outfit Changer (Database Version, Fixed Outfit)
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    -- Defina os looktypes fixos para masculino e feminino
    local maleOutfitID = 513 -- Outfit ID fixo para sexo masculino
    local femaleOutfitID = 513 -- Outfit ID fixo para sexo feminino

    -- Determinar o outfit com base no sexo do jogador
    local outfitID = player:getSex() == PLAYERSEX_MALE and maleOutfitID or femaleOutfitID

    -- Atualizar o looktype no banco de dados
    local query = string.format("UPDATE players SET looktype = %d WHERE id = %d", outfitID, player:getId())
    local success = db.query(query) -- Executa a consulta no banco de dados

    -- Debug: Verificar se a query foi executada
    if success then
        print(string.format("[Outfit Changer] Successfully updated looktype to %d for player ID %d.", outfitID, player:getId()))
    else
        print(string.format("[Outfit Changer] Failed to update looktype for player ID %d.", player:getId()))
    end

    -- Atualizar o outfit no jogo em tempo real
    local playerOutfit = player:getOutfit()
    playerOutfit.lookType = outfitID
    player:setOutfit(playerOutfit)

    -- Adicionar efeito visual e mensagem
    player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
    player:sendTextMessage(MESSAGE_INFO_DESCR, "Your appearance has been permanently changed!")

    -- Debug: Confirmar visual na tela do jogador
    print(string.format("[Outfit Changer] Player ID %d now has looktype %d.", player:getId(), outfitID))

    -- Remover o item usado
    item:remove(1)
    return true
end

otherwise nothing works

LUA:
-- Item Script for Outfit Changer
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local maleOutfitID = 513 -- Outfit ID para sexo masculino
    local femaleOutfitID = 513 -- Outfit ID para sexo feminino

    local outfitID = player:getSex() == PLAYERSEX_MALE and maleOutfitID or femaleOutfitID

    local playerOutfit = player:getOutfit()
    playerOutfit.lookType = outfitID
    player:setOutfit(playerOutfit)

    player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) -- Adiciona efeito visual

    player:sendTextMessage(MESSAGE_INFO_DESCR, "Your appearance has been changed!") -- Mensagem para o jogador

    item:remove(1) -- Remove 1 unidade do item após o uso
    return true
end

it activates 1 outfit, I don't know why.

1738117394993.webp
 
Back
Top