[OTClient + TFS] COLORIZE OUTFIT FOR CERTAIN TIME DURATION
Preview:
(If image is not loading, please click this link.)
About:
Basically, this pieces of code colorize creature outfit for all players on screen for certain time duration.
I made this for my own idea use, just simple: If monster cast spell Rage, it colorizes his outfit on red for certain time.
I wish to share it on OTLand, so everyone can use this feature/learn from it.
Requirements:
- TFS 1.X+ , any which handles packet sending by LUA.
- OTClient
Possible Bugs:
Not many, but if any player will appear on screen much time after creature uses colorize outfit function, it can not see "new" creature color because player appear on screen too late after. It can be possible bug but I made this like colorize outfit for ID of creature so this situation might not happen but I haven't tested this situation.
Let's copy-and-paste guyzZ:
OTClient:
This part, handling parsing packet from server and receiving it by client.
Search similar piece of codes that this one below and paste it after in :: protocolgame.cpp
protocolgame.h :: after void parseMapDescription(const InputMessagePtr& msg); :: paste:
Let's add this packet-read-by-client function in protocolgame.cpp
Declare this packet in protocolcodes.h , after :: GameServerChangeMapAwareRange
This part, is another NEW function to colorize outfit in OTClient, because existing functions colorize in strange way (one of them is just fadeIn color smoothly and stay in this color forever, in other one function, duration don't work for me, so I decided to make another one function [below]).
Add somewhere between void functions :: creature.cpp
Declaring function above (in spoiler), same "place", between void functions :: creature.h
Search similar piece of codes that this one below and paste it after in :: protocolgame.cpp
C++:
case Proto::GameServerMakeOutfitRed:
parseGameServerMakeOutfitRed(msg);
break;
C++:
void parseGameServerMakeOutfitRed(const InputMessagePtr& msg);
C++:
void ProtocolGame::parseGameServerMakeOutfitRed(const InputMessagePtr& msg)
{
uint id = msg->getU32();
uint duration = msg->getU32();
CreaturePtr creature = g_map.getCreatureById(id);
if(creature)
creature->setInstantOutfitColor(Color::red, duration);
}
C++:
GameServerMakeOutfitRed = 52,
Add somewhere between void functions :: creature.cpp
C++:
void Creature::setInstantOutfitColor(const Color& color, int duration)
{
if (duration > 0) {
m_outfitColor = color;
// This part below is need to back "from color" to normal outfit after X duration
auto self = static_self_cast<Creature>();
g_dispatcher.scheduleEvent([=] {
self->setOutfitColor(Color::white, 0);
}, duration*1000+500); // this "+500" it's to handle time with server script, you must experiment with this duration timer by your own to get all things fit in time.
}
}
C++:
void setInstantOutfitColor(const Color& color, int duration);
This part, is function in LUA that sending packet from server to client with creatureID (creature that needs to be colored) and duration (how many seconds will be in new color).
Add below function in :: data/lib/core/player.lua (or somewhere else where you got similar functions to send packets via LUA)
This part, is spell that doing something like read all players (spectators) from caster screen (creature that needs to get colored) and sending them packet to color caster outfit.
Don't forget to add in spells.xml too / lol / :: data/spells/scripts/rage.lua
Part of increasing damage if Monster got STORAGE_MONSTERRAGE you must do by yourself (onHealthChange in CreatureScripts), because I don't know if you got feature that monsters can have storages in your TFS. Basically that's all.
Add below function in :: data/lib/core/player.lua (or somewhere else where you got similar functions to send packets via LUA)
Lua:
function Player.rageCreature(self, creatureID, duration)
local networkMessage = NetworkMessage()
networkMessage:addByte(0x34) -- It's packet :: 52 OTC
networkMessage:addU32(creatureID)
networkMessage:addU32(duration)
networkMessage:sendToPlayer(self)
networkMessage:delete()
return true
end
This part, is spell that doing something like read all players (spectators) from caster screen (creature that needs to get colored) and sending them packet to color caster outfit.
Don't forget to add in spells.xml too / lol / :: data/spells/scripts/rage.lua
Lua:
local function debuffRage(cid)
local creature = Creature(cid)
if(not Creature(cid)) then
return
end
creature:setStorageValue(STORAGE_MONSTERRAGE, -1)
creature:getPosition():sendMagicEffect(43)
creature:say("Huh..", TALKTYPE_MONSTER_SAY)
return true
end
function onCastSpell(creature, var)
local rageTime = 6 -- Rage Time duration, how many seconds will be enraged, after that time outfit returns to previous color (removes it in my case).
local AreaX = 13 -- X axis range to whom to send the packet (monster view range)
local AreaY = 8 -- Y axis range to whom to send the packet (monster view range)
-- If creature already got enraged this spell must not cast again
if creature:getStorageValue(STORAGE_MONSTERRAGE) == 1 then
return true
end
-- Sending packet to all players around creature
local spectators = Game.getSpectators(creature:getPosition(), false, true, AreaX, AreaX, AreaY, AreaY)
if #spectators == 0 then
return nil
end
for index, spectator in ipairs(spectators) do
if spectator:getId() ~= creature then
creatureID = creature:getId()
-- This is usage of function that you pasted while ago in :: data/lib/core/player.lua
spectator:rageCreature(creatureID,rageTime)
end
end
local creaturePos = creature:getPosition()
local effectPos = creature:getPosition()+Position(1,1,0)
local target = creature:getTarget()
creature:setNoMove(true)
effectPos:sendMagicEffect(255)
creature:say("You making me angry..", TALKTYPE_MONSTER_SAY)
addEvent(function() Game.sendAnimatedText("RAGE!", creaturePos, 180) end, 200, creature.uid)
addEvent(function()
effectPos:sendMagicEffect(255)
creaturePos:sendMagicEffect(2)
creature:setStorageValue(STORAGE_MONSTERRAGE, 1)
creature:setNoMove(false)
addEvent(debuffRage, rageTime * 1000, creature.uid)
end, 500, creature.uid)
return true
end
Part of increasing damage if Monster got STORAGE_MONSTERRAGE you must do by yourself (onHealthChange in CreatureScripts), because I don't know if you got feature that monsters can have storages in your TFS. Basically that's all.
So basically that's all.
If you read all code carefully you will understand how to use new function to colorize outfit into red color.
If someone can upgrade this code (in OTC) that will colorize outfit to color declared and sent in packet for example: spectator:rageCreature(creatureID,rageTime,color)
I will be very glad to get, because right now I have more things to do
I will make it later for sure, but now I shared this quick feature.
Hope this feature can explain something to new OT-maker's and will be helpful to anyone
Enjoy! Have a good day! Peace~If you read all code carefully you will understand how to use new function to colorize outfit into red color.
If someone can upgrade this code (in OTC) that will colorize outfit to color declared and sent in packet for example: spectator:rageCreature(creatureID,rageTime,color)
I will be very glad to get, because right now I have more things to do
I will make it later for sure, but now I shared this quick feature.
Hope this feature can explain something to new OT-maker's and will be helpful to anyone