Because no one has bought or will buy this, i release this to the public.
This requires an edit on sources (All scripts are 100% written by me)
Here is a video: Fly System By Darkhaos
(Yes you can fly on water, i didn't recorded it because i forgot it xP)
Update Log:
Create a file on data/lib called 075-fly.lua and paste this:
Create a file on data/talkactions called fly.lua and paste this:
Create a file on data/movements called fly.lua and paste this:
Paste this inside your login.lua script at data/creaturescripts:
And this:
Create a file on data/creaturescripts called logout.lua and paste this:
Paste this on talkactions.xml:
Paste this on moveevents.xml:
Paste this on creaturescripts.xml:
Now comes the source edit...
Go to game.cpp and find the function:
[cpp]bool Game::combatBlockHit(CombatType_t combatType, Creature* attacker, Creature* target,
int32_t& healthChange, bool checkDefense, bool checkArmor)[/cpp]
And replace with this:
[cpp]bool Game::combatBlockHit(CombatType_t combatType, Creature* attacker, Creature* target,
int32_t& healthChange, bool checkDefense, bool checkArmor)
{
if(healthChange > 0)
return false;
const Position& targetPos = target->getPosition();
const SpectatorVec& list = getSpectators(targetPos);
if(!target->isAttackable() || Combat::canDoCombat(attacker, target) != RET_NOERROR)
{
std::string value;
MagicEffect_t eff = MAGIC_EFFECT_POFF;
if(target->getStorage(g_config.getNumber(ConfigManager::FLY_STORAGE), value) && atoi(value.c_str()) > 0)
eff = MAGIC_EFFECT_NONE;
addMagicEffect(list, targetPos, eff, target->isGhost());
return true;
}
int32_t damage = -healthChange;
BlockType_t blockType = target->blockHit(attacker, combatType, damage, checkDefense, checkArmor);
healthChange = -damage;
if(blockType == BLOCK_DEFENSE)
{
addMagicEffect(list, targetPos, MAGIC_EFFECT_POFF);
return true;
}
else if(blockType == BLOCK_ARMOR)
{
addMagicEffect(list, targetPos, MAGIC_EFFECT_BLOCKHIT);
return true;
}
else if(blockType != BLOCK_IMMUNITY)
return false;
MagicEffect_t effect = MAGIC_EFFECT_NONE;
switch(combatType)
{
case COMBAT_UNDEFINEDDAMAGE:
break;
case COMBAT_ENERGYDAMAGE:
case COMBAT_FIREDAMAGE:
case COMBAT_PHYSICALDAMAGE:
case COMBAT_ICEDAMAGE:
case COMBAT_DEATHDAMAGE:
case COMBAT_EARTHDAMAGE:
case COMBAT_HOLYDAMAGE:
{
effect = MAGIC_EFFECT_BLOCKHIT;
break;
}
default:
{
effect = MAGIC_EFFECT_POFF;
std::string value;
if(target->getStorage(g_config.getNumber(ConfigManager::FLY_STORAGE), value) && atoi(value.c_str()) > 0)
effect = MAGIC_EFFECT_NONE;
break;
}
}
addMagicEffect(list, targetPos, effect);
return true;
}
[/cpp]
Find the function:
[cpp]bool Game::combatChangeHealth(CombatType_t combatType, Creature* attacker, Creature* target, int32_t healthChange,
MagicEffect_t hitEffect/* = MAGIC_EFFECT_UNKNOWN*/, TextColor_t hitColor/* = TEXTCOLOR_UNKNOWN*/, bool force/* = false*/)[/cpp]
And replace with this:
[cpp]bool Game::combatChangeHealth(CombatType_t combatType, Creature* attacker, Creature* target, int32_t healthChange,
MagicEffect_t hitEffect/* = MAGIC_EFFECT_UNKNOWN*/, TextColor_t hitColor/* = TEXTCOLOR_UNKNOWN*/, bool force/* = false*/)
{
const Position& targetPos = target->getPosition();
if(healthChange > 0)
{
if(!force && target->getHealth() <= 0)
return false;
bool deny = false;
CreatureEventList statsChangeEvents = target->getCreatureEvents(CREATURE_EVENT_STATSCHANGE);
for(CreatureEventList::iterator it = statsChangeEvents.begin(); it != statsChangeEvents.end(); ++it)
{
if(!(*it)->executeStatsChange(target, attacker, STATSCHANGE_HEALTHGAIN, combatType, healthChange))
deny = true;
}
if(deny)
return false;
target->gainHealth(attacker, healthChange);
if(g_config.getBool(ConfigManager::SHOW_HEALING_DAMAGE) && !target->isGhost() &&
(g_config.getBool(ConfigManager::SHOW_HEALING_DAMAGE_MONSTER) || !target->getMonster()))
{
char buffer[20];
sprintf(buffer, "+%d", healthChange);
const SpectatorVec& list = getSpectators(targetPos);
if(combatType != COMBAT_HEALING)
addMagicEffect(list, targetPos, MAGIC_EFFECT_WRAPS_BLUE);
addAnimatedText(list, targetPos, TEXTCOLOR_GREEN, buffer);
}
}
else
{
const SpectatorVec& list = getSpectators(targetPos);
if(!target->isAttackable() || Combat::canDoCombat(attacker, target) != RET_NOERROR)
{
std::string value;
MagicEffect_t eff = MAGIC_EFFECT_POFF;
if(target->getStorage(g_config.getNumber(ConfigManager::FLY_STORAGE), value) && atoi(value.c_str()) > 0)
eff = MAGIC_EFFECT_NONE;
addMagicEffect(list, targetPos, eff);
return true;
}
int32_t damage = -healthChange;
if(damage != 0)
{
if(target->hasCondition(CONDITION_MANASHIELD) && combatType != COMBAT_UNDEFINEDDAMAGE)
{
int32_t manaDamage = std::min(target->getMana(), damage);
damage = std::max((int32_t)0, damage - manaDamage);
if(manaDamage != 0)
{
bool deny = false;
CreatureEventList statsChangeEvents = target->getCreatureEvents(CREATURE_EVENT_STATSCHANGE);
for(CreatureEventList::iterator it = statsChangeEvents.begin(); it != statsChangeEvents.end(); ++it)
{
if(!(*it)->executeStatsChange(target, attacker, STATSCHANGE_MANALOSS, combatType, manaDamage))
deny = true;
}
if(deny)
return false;
target->drainMana(attacker, combatType, manaDamage);
char buffer[20];
sprintf(buffer, "%d", manaDamage);
addMagicEffect(list, targetPos, MAGIC_EFFECT_LOSE_ENERGY);
addAnimatedText(list, targetPos, TEXTCOLOR_BLUE, buffer);
}
}
damage = std::min(target->getHealth(), damage);
if(damage > 0)
{
bool deny = false;
CreatureEventList statsChangeEvents = target->getCreatureEvents(CREATURE_EVENT_STATSCHANGE);
for(CreatureEventList::iterator it = statsChangeEvents.begin(); it != statsChangeEvents.end(); ++it)
{
if(!(*it)->executeStatsChange(target, attacker, STATSCHANGE_HEALTHLOSS, combatType, damage))
deny = true;
}
if(deny)
return false;
target->drainHealth(attacker, combatType, damage);
addCreatureHealth(list, target);
TextColor_t textColor = TEXTCOLOR_NONE;
MagicEffect_t magicEffect = MAGIC_EFFECT_NONE;
switch(combatType)
{
case COMBAT_PHYSICALDAMAGE:
{
Item* splash = NULL;
switch(target->getRace())
{
case RACE_VENOM:
textColor = TEXTCOLOR_LIGHTGREEN;
magicEffect = MAGIC_EFFECT_POISON;
splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_GREEN);
break;
case RACE_BLOOD:
textColor = TEXTCOLOR_RED;
magicEffect = MAGIC_EFFECT_DRAW_BLOOD;
splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_BLOOD);
break;
case RACE_UNDEAD:
textColor = TEXTCOLOR_GREY;
magicEffect = MAGIC_EFFECT_HIT_AREA;
break;
case RACE_FIRE:
textColor = TEXTCOLOR_ORANGE;
magicEffect = MAGIC_EFFECT_DRAW_BLOOD;
break;
case RACE_ENERGY:
textColor = TEXTCOLOR_PURPLE;
magicEffect = MAGIC_EFFECT_PURPLEENERGY;
break;
default:
break;
}
if(splash)
{
internalAddItem(NULL, target->getTile(), splash, INDEX_WHEREEVER, FLAG_NOLIMIT);
startDecay(splash);
}
break;
}
case COMBAT_ENERGYDAMAGE:
{
textColor = TEXTCOLOR_PURPLE;
magicEffect = MAGIC_EFFECT_ENERGY_DAMAGE;
break;
}
case COMBAT_EARTHDAMAGE:
{
textColor = TEXTCOLOR_LIGHTGREEN;
magicEffect = MAGIC_EFFECT_POISON_RINGS;
break;
}
case COMBAT_DROWNDAMAGE:
{
textColor = TEXTCOLOR_LIGHTBLUE;
magicEffect = MAGIC_EFFECT_LOSE_ENERGY;
break;
}
case COMBAT_FIREDAMAGE:
{
textColor = TEXTCOLOR_ORANGE;
magicEffect = MAGIC_EFFECT_HITBY_FIRE;
break;
}
case COMBAT_ICEDAMAGE:
{
textColor = TEXTCOLOR_TEAL;
magicEffect = MAGIC_EFFECT_ICEATTACK;
break;
}
case COMBAT_HOLYDAMAGE:
{
textColor = TEXTCOLOR_YELLOW;
magicEffect = MAGIC_EFFECT_HOLYDAMAGE;
break;
}
case COMBAT_DEATHDAMAGE:
{
textColor = TEXTCOLOR_DARKRED;
magicEffect = MAGIC_EFFECT_SMALLCLOUDS;
break;
}
case COMBAT_LIFEDRAIN:
{
textColor = TEXTCOLOR_RED;
magicEffect = MAGIC_EFFECT_WRAPS_RED;
break;
}
default:
break;
}
if(hitEffect != MAGIC_EFFECT_UNKNOWN)
magicEffect = hitEffect;
if(hitColor != TEXTCOLOR_UNKNOWN)
textColor = hitColor;
if(textColor < TEXTCOLOR_NONE && magicEffect < MAGIC_EFFECT_NONE)
{
char buffer[20];
sprintf(buffer, "%d", damage);
addMagicEffect(list, targetPos, magicEffect);
addAnimatedText(list, targetPos, textColor, buffer);
}
}
}
}
return true;
}
[/code]
Find the function:
And you're done
Please post all bugs here.
Rep++ will be appreciated.
¡Happy Christmas!
You can find all files here, also there is a file that explain all variables on 075-fly.lua
View attachment Fly System By Darkhaos.rar
This requires an edit on sources (All scripts are 100% written by me)
Here is a video: Fly System By Darkhaos
(Yes you can fly on water, i didn't recorded it because i forgot it xP)
- Updated At: Wednesday December 29th, 2010 at 01:26 A.M (GMT -4:30)
- Last Tested At: Wednesday December 29th, 2010 at 01:26 A.M (GMT -4:30)
- Tested On: The Forgotten Server 0.3.6pl1
Update Log:
Code:
[b]V0.2: [28 / 12 / 2010][/B]
- Fixed a bug, now you can't stop flying on water
- Added a new feature, now you can enable/disable if fly system will change player speeds.
[B]V0.1: [24 / 12 / 2010][/B]
- Release of the script.
Create a file on data/lib called 075-fly.lua and paste this:
Lua:
-- ///////////////////////////////////////////////////
-- //// Fly System By Darkhaos ////
-- ////////////////////// V. 0.2 /////////////////////
-- ////////////////// Contact: Otland/////////////////
-- ///////////////////////////////////////////////////
FLY_STORAGE = getConfigValue("flyStorage")
flyBlackSQM = false
nonFlyableBorder = {7576, 7577}
changeSpeed = true
flySpeed = 800
waterSpeed = 150
ITEM_FLYTILE = 460
ITEM_WATERTILE = 4625
FLY_OUTFIT = {lookType = 239, lookHead = 0, lookBody = 0, lookLegs = 0, lookFeet = 0, lookTypeEx = 0, lookAddons = 0}
WATER = {4608, 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, 4617, 4618, 4619}
RANGEX = 1
RANGEY = 1
ret =
{
"You are now flying.",
"You are not flying anymore.",
"You cannot stop flying here.",
"You are not flying.",
"You cannot up here.",
"You cannot down here.",
"You cannot go to there."
}
storPos = {x = 1200, y = 1201, z = 1202}
function isWalkable(pos, creature, proj, pz)
if getTileThingByPos({x = pos.x, y = pos.y, z = pos.z, stackpos = 0}).itemid == 0 then return false end
if getTopCreature(pos).uid > 0 and creature then return false end
if getTileInfo(pos).protection and pz then return false, true end
local n = not proj and 3 or 2
for i = 0, 255 do
pos.stackpos = i
local tile = getTileThingByPos(pos)
if tile.itemid ~= 0 and not isCreature(tile.uid) then
if hasProperty(tile.uid, n) or hasProperty(tile.uid, 7) then
return false
end
end
end
return true
end
function getAreaToRemove(pos1, pos2)
local t = getDirectionTo(pos1, pos2)
local pos =
{
[0] =
{
{x = pos1.x + 1, y = pos1.y + 1, z = pos1.z},
{x = pos1.x, y = pos1.y + 1, z = pos1.z},
{x = pos1.x - 1, y = pos1.y + 1, z = pos1.z}
},
[2] =
{
{x = pos1.x + 1, y = pos1.y - 1, z = pos1.z},
{x = pos1.x, y = pos1.y - 1, z = pos1.z},
{x = pos1.x - 1, y = pos1.y - 1, z = pos1.z}
},
[1] =
{
{x = pos1.x - 1, y = pos1.y - 1, z = pos1.z},
{x = pos1.x - 1, y = pos1.y, z = pos1.z},
{x = pos1.x - 1, y = pos1.y + 1, z = pos1.z}
},
[3] =
{
{x = pos1.x + 1, y = pos1.y - 1, z = pos1.z},
{x = pos1.x + 1, y = pos1.y, z = pos1.z},
{x = pos1.x + 1, y = pos1.y + 1, z = pos1.z}
},
[7] =
{
{x = pos1.x - 1, y = pos1.y - 1, z = pos1.z},
{x = pos1.x - 1, y = pos1.y, z = pos1.z},
{x = pos1.x - 1, y = pos1.y + 1, z = pos1.z},
{x = pos1.x, y = pos1.y + 1, z = pos1.z},
{x = pos1.x + 1, y = pos1.y + 1, z = pos1.z}
},
[6] =
{
{x = pos1.x + 1, y = pos1.y - 1, z = pos1.z},
{x = pos1.x + 1, y = pos1.y, z = pos1.z},
{x = pos1.x + 1, y = pos1.y + 1, z = pos1.z},
{x = pos1.x, y = pos1.y + 1, z = pos1.z},
{x = pos1.x - 1, y = pos1.y + 1, z = pos1.z}
},
[5] =
{
{x = pos1.x - 1, y = pos1.y - 1, z = pos1.z},
{x = pos1.x - 1, y = pos1.y, z = pos1.z},
{x = pos1.x - 1, y = pos1.y + 1, z = pos1.z},
{x = pos1.x, y = pos1.y - 1, z = pos1.z},
{x = pos1.x + 1, y = pos1.y - 1, z = pos1.z}
},
[4] =
{
{x = pos1.x - 1, y = pos1.y - 1, z = pos1.z},
{x = pos1.x, y = pos1.y - 1, z = pos1.z},
{x = pos1.x + 1, y = pos1.y - 1, z = pos1.z},
{x = pos1.x + 1, y = pos1.y, z = pos1.z},
{x = pos1.x + 1, y = pos1.y + 1, z = pos1.z}
}
}
return pos[t]
end
function doCreateTile(pos)
doAreaCombatHealth(0, 0, pos, 0, 0, 0, 255)
end
Create a file on data/talkactions called fly.lua and paste this:
Lua:
-- ///////////////////////////////////////////////////
-- //// Fly System By Darkhaos ////
-- ////////////////////// V. 0.2 /////////////////////
-- ////////////////// Contact: Otland/////////////////
-- ///////////////////////////////////////////////////
function onSay(cid, words, param)
local pos = getCreaturePosition(cid)
pos.stackpos = 0
if(words == "!fly") then
if getCreatureStorage(cid, FLY_STORAGE) > 0 then
if not isWalkable(getCreaturePosition(cid)) or getThingFromPos(pos).itemid == ITEM_FLYTILE or getThingFromPos(pos).itemid == ITEM_WATERTILE then
doPlayerSendCancel(cid, ret[3])
return true
end
doChangeSpeed(cid, -getCreatureSpeed(cid) + getCreatureBaseSpeed(cid))
doCreatureSetStorage(cid, FLY_STORAGE, 0)
doRemoveCondition(cid, CONDITION_OUTFIT)
doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, ret[2])
return true
else
doCreatureSetStorage(cid, FLY_STORAGE, 1)
doRemoveConditions(cid, true)
doSetCreatureOutfit(cid, FLY_OUTFIT, -1)
doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, ret[1])
if changeSpeed then
doChangeSpeed(cid, flySpeed)
end
return true
end
elseif(words == "fly") then
if param == "up" then
pos.z = pos.z - 1
doCreateTile(pos)
if getCreatureStorage(cid, FLY_STORAGE) < 1 then
doPlayerSendCancel(cid, ret[4])
return true
end
if(getCreaturePosition(cid).z == 0) or (getThingFromPos(pos).itemid ~= ITEM_FLYTILE and getThingFromPos(pos).itemid > 0) or (getTileInfo(pos).house) then
doPlayerSendCancel(cid, ret[5])
return true
end
local tpos = pos
tpos.stackpos = 253
if isCreature(getThingFromPos(tpos).uid) then
doPlayerSendCancel(cid, ret[5])
return true
end
local toCreate = {}
for _, area in ipairs(getArea(pos, RANGEX, RANGEY)) do
doCreateTile(area)
local thing = getThingFromPos(area)
if thing.itemid < 1 then
table.insert(toCreate, area)
end
end
if getThingFromPos(pos).itemid < 1 then
for _, create in ipairs(toCreate) do
create.stackpos = 0
doCreateItem(ITEM_FLYTILE, 1, create)
end
doTeleportThing(cid, pos)
if changeSpeed then
doChangeSpeed(cid, flySpeed)
end
pos.z = pos.z + 1
doSendMagicEffect(pos, CONST_ME_BLOCKHIT)
for _, area in ipairs(getArea(pos, RANGEX, RANGEY)) do
doCreateTile(area)
local thing = getThingFromPos(area)
if thing.itemid == ITEM_FLYTILE then
doRemoveItem(thing.uid)
elseif thing.itemid == ITEM_WATERTILE then
doTransformItem(thing.uid, WATER[1])
end
end
else
doPlayerSendCancel(cid, ret[7])
end
elseif param == "down" then
pos.z = pos.z + 1
doCreateTile(pos)
if getCreatureStorage(cid, FLY_STORAGE) < 1 then
doPlayerSendCancel(cid, ret[4])
return true
end
if getCreaturePosition(cid).z == 14 then
doPlayerSendCancel(cid, ret[6])
return true
end
if(getTileInfo(pos).house) then
doPlayerSendCancel(cid, ret[6])
return true
end
local cpos = getCreaturePosition(cid)
cpos.stackpos = 0
if getThingFromPos(cpos).itemid ~= ITEM_FLYTILE then
doPlayerSendCancel(cid, ret[6])
return true
end
local tpos = pos
tpos.stackpos = 253
if isCreature(getThingFromPos(tpos).uid) then
doPlayerSendCancel(cid, ret[6])
return true
end
local toCreate = {}
for _, area in ipairs(getArea(pos, RANGEX, RANGEY)) do
doCreateTile(area)
local thing = getThingFromPos(area)
if(thing.itemid < 1 or isInArray(WATER, thing.itemid)) then
table.insert(toCreate, area)
end
end
local x = false
if isWalkable(pos) or getThingFromPos(pos).itemid < 1 or isInArray(WATER, getThingFromPos(pos).itemid) then
for _, create in ipairs(toCreate) do
if isInArray(WATER, getThingFromPos(create).itemid) then
doTransformItem(getThingFromPos(create).uid, ITEM_WATERTILE)
x = (create.z == pos.z and true or false)
else
doCreateItem(ITEM_FLYTILE, 1, create)
end
end
doTeleportThing(cid, pos)
doSendMagicEffect(pos, (x and CONST_ME_WATERSPLASH or getThingFromPos(pos).itemid == ITEM_WATERTILE and CONST_ME_WATERSPLASH or CONST_ME_NONE))
if changeSpeed then
doChangeSpeed(cid, (x and (-getCreatureSpeed(cid) + waterSpeed + getCreatureBaseSpeed(cid)) or (-getCreatureSpeed(cid) + flySpeed + getCreatureBaseSpeed(cid))))
end
pos.z = pos.z - 1
doSendMagicEffect(pos, CONST_ME_BLOCKHIT)
for _, area in ipairs(getArea(pos, RANGEX, RANGEY)) do
local thing = getThingFromPos(area)
if thing.itemid == ITEM_FLYTILE then
doRemoveItem(thing.uid)
end
end
else
doPlayerSendCancel(cid, ret[7])
end
end
end
return true
end
Create a file on data/movements called fly.lua and paste this:
Lua:
-- ///////////////////////////////////////////////////
-- //// Fly System By Darkhaos ////
-- ////////////////////// V. 0.2 /////////////////////
-- ////////////////// Contact: Otland/////////////////
-- ///////////////////////////////////////////////////
function onStepIn(cid, item, position, lastPosition, fromPosition, toPosition, actor)
if isInArray({ITEM_FLYTILE, ITEM_WATERTILE}, item.itemid) then
if not isPlayer(cid) then
doTeleportThing(cid, fromPosition)
return true
end
if getCreatureStorage(cid, FLY_STORAGE) < 1 then
doPlayerSendCancel(cid, ret[4])
doTeleportThing(cid, fromPosition)
return true
end
local toPos = toPosition
toPos.stackpos = 0
if not flyBlackSQM then
toPos.z = 7
doCreateTile(toPos)
if getThingFromPos(toPos).itemid < 1 or getThingFromPos(toPos).itemid == ITEM_FLYTILE then
doTeleportThing(cid, fromPosition)
return true
end
toPos.z = toPosition.z
end
if(getTileInfo(toPos).house) then
doTeleportThing(cid, fromPosition)
return true
end
if nonFlyableBorder and type(nonFlyableBorder) == "table" then
for i = toPos.z, 14 do
toPos.z = i
toPos.stackpos = 1
doCreateTile(toPos)
if isInArray(nonFlyableBorder, getThingFromPos(toPos).itemid) then
doTeleportThing(cid, fromPosition)
return true
end
end
toPos.z = getCreaturePosition(cid).z
toPos.stackpos = 0
end
for _, area in ipairs(getArea(toPos, RANGEX, RANGEY)) do
doCreateTile(area)
local thing = getThingFromPos(area)
if thing.itemid < 1 or thing.itemid == ITEM_FLYTILE then
doCreateItem(ITEM_FLYTILE, 1, area)
elseif thing.itemid == ITEM_WATERTILE or isInArray(WATER, thing.itemid) then
doTransformItem(thing.uid, ITEM_WATERTILE)
end
end
end
return true
end
function onStepOut(cid, item, position, lastPosition, fromPosition, toPosition, actor)
local area = getAreaToRemove(fromPosition, toPosition)
for _, arear in ipairs(area) do
doCreateTile(arear)
local thing = getThingFromPos(arear)
if thing.itemid == ITEM_FLYTILE then
doRemoveItem(thing.uid)
elseif thing.itemid == ITEM_WATERTILE then
doTransformItem(thing.uid, WATER[1])
end
end
return true
end
Paste this inside your login.lua script at data/creaturescripts:
Lua:
-- ///////////////////////////////////////////////////
-- //// Fly System By Darkhaos ////
-- ////////////////////// V. 0.2 /////////////////////
-- ////////////////// Contact: Otland/////////////////
-- ///////////////////////////////////////////////////
function onLogin(cid)
if getCreatureStorage(cid, FLY_STORAGE) > 0 then
local storpos = {x = getCreatureStorage(cid, storPos.x), y = getCreatureStorage(cid, storPos.y), z = getCreatureStorage(cid, storPos.z), stackpos = 0}
doCreateTile(storpos)
local thing = getThingFromPos(storpos)
if thing.itemid < 1 or isInArray(WATER, thing.itemid) then
for _, area in ipairs(getArea(storpos, RANGEX, RANGEY)) do
doCreateTile(area)
local thing = getThingFromPos(area)
if thing.itemid < 1 then
doCreateItem(ITEM_FLYTILE, 1, area)
elseif isInArray(WATER, getThingFromPos(area).itemid) then
doTransformItem(getThingFromPos(area).uid, ITEM_WATERTILE)
end
end
end
doRemoveConditions(cid, true)
doSetCreatureOutfit(cid, FLY_OUTFIT, -1)
doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "You are now flying.")
doTeleportThing(cid, storpos)
return true
end
end
And this:
Lua:
registerCreatureEvent(cid, "PlayerLogout")
Create a file on data/creaturescripts called logout.lua and paste this:
Lua:
-- ///////////////////////////////////////////////////
-- //// Fly System By Darkhaos ////
-- ////////////////////// V. 0.2 /////////////////////
-- ////////////////// Contact: Otland/////////////////
-- ///////////////////////////////////////////////////
function onLogout(cid)
if getCreatureStorage(cid, FLY_STORAGE) > 0 then
local pos = getCreaturePosition(cid)
pos.stackpos = 0
for _, area in ipairs(getArea(pos, RANGEX, RANGEY)) do
doCreateTile(area)
local thing = getThingFromPos(area)
if thing.itemid == ITEM_FLYTILE then
doRemoveItem(thing.uid)
elseif thing.itemid == ITEM_WATERTILE then
doTransformItem(thing.uid, WATER[1])
end
end
doCreatureSetStorage(cid, storPos.x, pos.x)
doCreatureSetStorage(cid, storPos.y, pos.y)
doCreatureSetStorage(cid, storPos.z, pos.z)
end
return true
end
Paste this on talkactions.xml:
XML:
<talkaction words="!fly;fly" case-sensitive="no" event="script" value="fly.lua"/>
Paste this on moveevents.xml:
XML:
<movevent type="StepIn" itemid="460" event="script" value="fly.lua"/>
<movevent type="StepOut" itemid="460" event="script" value="fly.lua"/>
<movevent type="StepIn" itemid="4609-4619" event="script" value="fly.lua"/>
<movevent type="StepIn" itemid="4625" event="script" value="fly.lua"/>
Paste this on creaturescripts.xml:
XML:
<event type="logout" name="PlayerLogout" event="script" value="logout.lua"/>
Now comes the source edit...
Go to game.cpp and find the function:
[cpp]bool Game::combatBlockHit(CombatType_t combatType, Creature* attacker, Creature* target,
int32_t& healthChange, bool checkDefense, bool checkArmor)[/cpp]
And replace with this:
[cpp]bool Game::combatBlockHit(CombatType_t combatType, Creature* attacker, Creature* target,
int32_t& healthChange, bool checkDefense, bool checkArmor)
{
if(healthChange > 0)
return false;
const Position& targetPos = target->getPosition();
const SpectatorVec& list = getSpectators(targetPos);
if(!target->isAttackable() || Combat::canDoCombat(attacker, target) != RET_NOERROR)
{
std::string value;
MagicEffect_t eff = MAGIC_EFFECT_POFF;
if(target->getStorage(g_config.getNumber(ConfigManager::FLY_STORAGE), value) && atoi(value.c_str()) > 0)
eff = MAGIC_EFFECT_NONE;
addMagicEffect(list, targetPos, eff, target->isGhost());
return true;
}
int32_t damage = -healthChange;
BlockType_t blockType = target->blockHit(attacker, combatType, damage, checkDefense, checkArmor);
healthChange = -damage;
if(blockType == BLOCK_DEFENSE)
{
addMagicEffect(list, targetPos, MAGIC_EFFECT_POFF);
return true;
}
else if(blockType == BLOCK_ARMOR)
{
addMagicEffect(list, targetPos, MAGIC_EFFECT_BLOCKHIT);
return true;
}
else if(blockType != BLOCK_IMMUNITY)
return false;
MagicEffect_t effect = MAGIC_EFFECT_NONE;
switch(combatType)
{
case COMBAT_UNDEFINEDDAMAGE:
break;
case COMBAT_ENERGYDAMAGE:
case COMBAT_FIREDAMAGE:
case COMBAT_PHYSICALDAMAGE:
case COMBAT_ICEDAMAGE:
case COMBAT_DEATHDAMAGE:
case COMBAT_EARTHDAMAGE:
case COMBAT_HOLYDAMAGE:
{
effect = MAGIC_EFFECT_BLOCKHIT;
break;
}
default:
{
effect = MAGIC_EFFECT_POFF;
std::string value;
if(target->getStorage(g_config.getNumber(ConfigManager::FLY_STORAGE), value) && atoi(value.c_str()) > 0)
effect = MAGIC_EFFECT_NONE;
break;
}
}
addMagicEffect(list, targetPos, effect);
return true;
}
[/cpp]
Find the function:
[cpp]bool Game::combatChangeHealth(CombatType_t combatType, Creature* attacker, Creature* target, int32_t healthChange,
MagicEffect_t hitEffect/* = MAGIC_EFFECT_UNKNOWN*/, TextColor_t hitColor/* = TEXTCOLOR_UNKNOWN*/, bool force/* = false*/)[/cpp]
And replace with this:
[cpp]bool Game::combatChangeHealth(CombatType_t combatType, Creature* attacker, Creature* target, int32_t healthChange,
MagicEffect_t hitEffect/* = MAGIC_EFFECT_UNKNOWN*/, TextColor_t hitColor/* = TEXTCOLOR_UNKNOWN*/, bool force/* = false*/)
{
const Position& targetPos = target->getPosition();
if(healthChange > 0)
{
if(!force && target->getHealth() <= 0)
return false;
bool deny = false;
CreatureEventList statsChangeEvents = target->getCreatureEvents(CREATURE_EVENT_STATSCHANGE);
for(CreatureEventList::iterator it = statsChangeEvents.begin(); it != statsChangeEvents.end(); ++it)
{
if(!(*it)->executeStatsChange(target, attacker, STATSCHANGE_HEALTHGAIN, combatType, healthChange))
deny = true;
}
if(deny)
return false;
target->gainHealth(attacker, healthChange);
if(g_config.getBool(ConfigManager::SHOW_HEALING_DAMAGE) && !target->isGhost() &&
(g_config.getBool(ConfigManager::SHOW_HEALING_DAMAGE_MONSTER) || !target->getMonster()))
{
char buffer[20];
sprintf(buffer, "+%d", healthChange);
const SpectatorVec& list = getSpectators(targetPos);
if(combatType != COMBAT_HEALING)
addMagicEffect(list, targetPos, MAGIC_EFFECT_WRAPS_BLUE);
addAnimatedText(list, targetPos, TEXTCOLOR_GREEN, buffer);
}
}
else
{
const SpectatorVec& list = getSpectators(targetPos);
if(!target->isAttackable() || Combat::canDoCombat(attacker, target) != RET_NOERROR)
{
std::string value;
MagicEffect_t eff = MAGIC_EFFECT_POFF;
if(target->getStorage(g_config.getNumber(ConfigManager::FLY_STORAGE), value) && atoi(value.c_str()) > 0)
eff = MAGIC_EFFECT_NONE;
addMagicEffect(list, targetPos, eff);
return true;
}
int32_t damage = -healthChange;
if(damage != 0)
{
if(target->hasCondition(CONDITION_MANASHIELD) && combatType != COMBAT_UNDEFINEDDAMAGE)
{
int32_t manaDamage = std::min(target->getMana(), damage);
damage = std::max((int32_t)0, damage - manaDamage);
if(manaDamage != 0)
{
bool deny = false;
CreatureEventList statsChangeEvents = target->getCreatureEvents(CREATURE_EVENT_STATSCHANGE);
for(CreatureEventList::iterator it = statsChangeEvents.begin(); it != statsChangeEvents.end(); ++it)
{
if(!(*it)->executeStatsChange(target, attacker, STATSCHANGE_MANALOSS, combatType, manaDamage))
deny = true;
}
if(deny)
return false;
target->drainMana(attacker, combatType, manaDamage);
char buffer[20];
sprintf(buffer, "%d", manaDamage);
addMagicEffect(list, targetPos, MAGIC_EFFECT_LOSE_ENERGY);
addAnimatedText(list, targetPos, TEXTCOLOR_BLUE, buffer);
}
}
damage = std::min(target->getHealth(), damage);
if(damage > 0)
{
bool deny = false;
CreatureEventList statsChangeEvents = target->getCreatureEvents(CREATURE_EVENT_STATSCHANGE);
for(CreatureEventList::iterator it = statsChangeEvents.begin(); it != statsChangeEvents.end(); ++it)
{
if(!(*it)->executeStatsChange(target, attacker, STATSCHANGE_HEALTHLOSS, combatType, damage))
deny = true;
}
if(deny)
return false;
target->drainHealth(attacker, combatType, damage);
addCreatureHealth(list, target);
TextColor_t textColor = TEXTCOLOR_NONE;
MagicEffect_t magicEffect = MAGIC_EFFECT_NONE;
switch(combatType)
{
case COMBAT_PHYSICALDAMAGE:
{
Item* splash = NULL;
switch(target->getRace())
{
case RACE_VENOM:
textColor = TEXTCOLOR_LIGHTGREEN;
magicEffect = MAGIC_EFFECT_POISON;
splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_GREEN);
break;
case RACE_BLOOD:
textColor = TEXTCOLOR_RED;
magicEffect = MAGIC_EFFECT_DRAW_BLOOD;
splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_BLOOD);
break;
case RACE_UNDEAD:
textColor = TEXTCOLOR_GREY;
magicEffect = MAGIC_EFFECT_HIT_AREA;
break;
case RACE_FIRE:
textColor = TEXTCOLOR_ORANGE;
magicEffect = MAGIC_EFFECT_DRAW_BLOOD;
break;
case RACE_ENERGY:
textColor = TEXTCOLOR_PURPLE;
magicEffect = MAGIC_EFFECT_PURPLEENERGY;
break;
default:
break;
}
if(splash)
{
internalAddItem(NULL, target->getTile(), splash, INDEX_WHEREEVER, FLAG_NOLIMIT);
startDecay(splash);
}
break;
}
case COMBAT_ENERGYDAMAGE:
{
textColor = TEXTCOLOR_PURPLE;
magicEffect = MAGIC_EFFECT_ENERGY_DAMAGE;
break;
}
case COMBAT_EARTHDAMAGE:
{
textColor = TEXTCOLOR_LIGHTGREEN;
magicEffect = MAGIC_EFFECT_POISON_RINGS;
break;
}
case COMBAT_DROWNDAMAGE:
{
textColor = TEXTCOLOR_LIGHTBLUE;
magicEffect = MAGIC_EFFECT_LOSE_ENERGY;
break;
}
case COMBAT_FIREDAMAGE:
{
textColor = TEXTCOLOR_ORANGE;
magicEffect = MAGIC_EFFECT_HITBY_FIRE;
break;
}
case COMBAT_ICEDAMAGE:
{
textColor = TEXTCOLOR_TEAL;
magicEffect = MAGIC_EFFECT_ICEATTACK;
break;
}
case COMBAT_HOLYDAMAGE:
{
textColor = TEXTCOLOR_YELLOW;
magicEffect = MAGIC_EFFECT_HOLYDAMAGE;
break;
}
case COMBAT_DEATHDAMAGE:
{
textColor = TEXTCOLOR_DARKRED;
magicEffect = MAGIC_EFFECT_SMALLCLOUDS;
break;
}
case COMBAT_LIFEDRAIN:
{
textColor = TEXTCOLOR_RED;
magicEffect = MAGIC_EFFECT_WRAPS_RED;
break;
}
default:
break;
}
if(hitEffect != MAGIC_EFFECT_UNKNOWN)
magicEffect = hitEffect;
if(hitColor != TEXTCOLOR_UNKNOWN)
textColor = hitColor;
if(textColor < TEXTCOLOR_NONE && magicEffect < MAGIC_EFFECT_NONE)
{
char buffer[20];
sprintf(buffer, "%d", damage);
addMagicEffect(list, targetPos, magicEffect);
addAnimatedText(list, targetPos, textColor, buffer);
}
}
}
}
return true;
}
[/code]
Find the function:
Code:
bool Game::combatChangeMana(Creature* attacker, Creature* target, int32_t manaChange)
[/cpp]
[B]And replace with this:[/B]
[cpp]bool Game::combatChangeMana(Creature* attacker, Creature* target, int32_t manaChange)
{
const Position& targetPos = target->getPosition();
if(manaChange > 0)
{
bool deny = false;
CreatureEventList statsChangeEvents = target->getCreatureEvents(CREATURE_EVENT_STATSCHANGE);
for(CreatureEventList::iterator it = statsChangeEvents.begin(); it != statsChangeEvents.end(); ++it)
{
if(!(*it)->executeStatsChange(target, attacker, STATSCHANGE_MANAGAIN, COMBAT_HEALING, manaChange))
deny = true;
}
if(deny)
return false;
target->changeMana(manaChange);
if(g_config.getBool(ConfigManager::SHOW_HEALING_DAMAGE) && !target->isGhost() &&
(g_config.getBool(ConfigManager::SHOW_HEALING_DAMAGE_MONSTER) || !target->getMonster()))
{
char buffer[20];
sprintf(buffer, "+%d", manaChange);
const SpectatorVec& list = getSpectators(targetPos);
addAnimatedText(list, targetPos, TEXTCOLOR_DARKPURPLE, buffer);
}
}
else
{
const SpectatorVec& list = getSpectators(targetPos);
if(!target->isAttackable() || Combat::canDoCombat(attacker, target) != RET_NOERROR)
{
std::string value;
MagicEffect_t eff = MAGIC_EFFECT_POFF;
if(target->getStorage(g_config.getNumber(ConfigManager::FLY_STORAGE), value) && atoi(value.c_str()) > 0)
eff = MAGIC_EFFECT_NONE;
addMagicEffect(list, targetPos, eff);
return false;
}
int32_t manaLoss = std::min(target->getMana(), -manaChange);
BlockType_t blockType = target->blockHit(attacker, COMBAT_MANADRAIN, manaLoss);
if(blockType != BLOCK_NONE)
{
addMagicEffect(list, targetPos, MAGIC_EFFECT_POFF);
return false;
}
if(manaLoss > 0)
{
bool deny = false;
CreatureEventList statsChangeEvents = target->getCreatureEvents(CREATURE_EVENT_STATSCHANGE);
for(CreatureEventList::iterator it = statsChangeEvents.begin(); it != statsChangeEvents.end(); ++it)
{
if(!(*it)->executeStatsChange(target, attacker, STATSCHANGE_MANALOSS, COMBAT_UNDEFINEDDAMAGE, manaChange))
deny = true;
}
if(deny)
return false;
target->drainMana(attacker, COMBAT_MANADRAIN, manaLoss);
char buffer[20];
sprintf(buffer, "%d", manaLoss);
addAnimatedText(list, targetPos, TEXTCOLOR_BLUE, buffer);
}
}
return true;
}
[/cpp]
[B]Go to [U][I]configmanager.cpp[/I][/U] and find this:[/B]
[cpp]m_confBool[ADDONS_PREMIUM] = getGlobalBool("addonsOnlyPremium", true);[/cpp]
[B]Below it, paste this:[/B]
[cpp]m_confNumber[FLY_STORAGE] = getGlobalNumber("flyStorage", 0);[/cpp]
[B]Go to [U][I]configmanager.h[/I][/U] and find this:[/B]
[cpp]HOUSE_CLEAN_OLD,[/cpp]
[B]Below it, paste this:[/B]
[cpp]FLY_STORAGE,[/cpp]
[B]Now add this to your [I][U]config.lua[/U][/I][/B]
[code] flyStorage = 65535
And you're done
Please post all bugs here.
Rep++ will be appreciated.
¡Happy Christmas!
You can find all files here, also there is a file that explain all variables on 075-fly.lua
View attachment Fly System By Darkhaos.rar
Last edited: