Oskar
Forum friend
- Dołączył
- Styczeń 24, 2009
- Posty
- 2256
- Liczba reakcji
- 331
Przygod? zaczynamy w folderze creaturescripts.
Tworzymy plik Combat.lua i wklejamy:
Plik Think.lua i wklejamy:
Do creaturescripts.xml wklejamy:
Do login.lua dodajemy:
Ko?czymy w?dr?wk? po tym folderze i kierujemy si? do data/lib/050-function.lua i wklejamy tam:
Do config.lua dodajemy:
Teraz folder monsters
Do ka?dego potwora, kt?rego trzeba sprowokowa? dodajemy (pod </flags>):
Z ka?dego takowego potwora usuwamy ataki (poza fizycznym i conditionami), na przyk?adzie Son of Verminor:
Jak wida? u?ywa on nowych czar?w, wi?c idziemy do data/spells/scripts i tworzymy tam dwa pliki o nazwach Square.lua oraz SoV.lua i wklejamy kolejno:
Do spells.xml dodajemy:
To tylko na przyk?adzie Son of Verminor, dla ka?dego potwora trzeba niestety robi? nowe czary (uroki LUA), dlaczego? Ano dlatego, ?e zwracaj?c false w funkcji onCombat potw?r i tak u?ywa czar?w.
Skrypt wymaga optymalizacji, nie testowa?em na wi?kszej ilo?ci potwor?w ani?eli ~40 naraz.
Tworzymy plik Combat.lua i wklejamy:
PHP:
monsters = {'ghastly dragon','son of verminor','infernalist','black knight','hero','braindeath','crystal spider','killer caiman','earth elemental','adept of the cult','marid','efreet','monk','dragon hatchling','mutated human','carniphila','tortoise','gang member','poacher','elf','goblin scavenger','goblin','crazed beggar','crab','panda','bug','spider','snake'}
--ghastly - 1, son of verminor - 1, infernalist - 1, bk - 0, hero - 1, braindeath - 1, crystal spider - 1, killer - 1, earth elemental - 1, adept - 0, marid - 1, efreet - 1, monk - 1, dragon - 1, mutated - 1, carniphila - 1, tortoise - 1, gang - 1, poacher - 1, elf - 1, goblin - 1, goblin - 1, crazed - 1, crab - 1, panda - 1, bug - 1, spider - 1, snake - 1
function onCombat(cid, target)
if isMonster(cid) and isInArray(monsters, getCreatureName(cid):lower()) then
if isPlayer(target) then
if getPlayerStorageValue(target, cid) == -1 then
return false
else
if getCreatureSpeed(cid) == 0 then
return doChangeSpeed(cid, getCreatureBaseSpeed(cid))
end
return true
end
elseif isSummon(target) then
if getCreatureSpeed(cid) == 0 then
doChangeSpeed(cid, getCreatureBaseSpeed(cid))
end
if getPlayerStorageValue(getCreatureMaster(target), cid) == -1 then
return false
else
return true
end
end
elseif isMonster(target) and isSummon(target) == false and isPlayer(cid) and isInArray(monsters, getCreatureName(target):lower()) then
if getPlayerStorageValue(cid, target) == -1 then
if getCreatureSpeed(target) == 0 then
doChangeSpeed(target, getCreatureBaseSpeed(target))
end
return doPlayerSetStorageValue(cid, target, 0)
end
end
return true
end
function onKill(cid, target, lastHit)
if isMonster(target) and isPlayer(cid) and isInArray(monsters, getCreatureName(target):lower()) then
if getPlayerStorageValue(cid, target) == 0 then
doPlayerSetStorageValue(cid, target, -1)
end
end
return true
end
PHP:
function onThink(cid)
if isMonster(cid) then
local s = {-1,1}
local pos, target, targets, distance = getCreaturePosition(cid), getCreatureTarget(cid), getMonsterTargetList(cid), getConfigValue('distanceBetweenPlayerAndMonster')
if target ~= 0 then
if isPlayer(target) then
if getPlayerStorageValue(target, cid) == -1 then
doChangeSpeed(cid, -getCreatureSpeed(cid))
doMonsterChangeTarget(cid)
if getCreatureStorage(cid, cid) ~= 0 then
if math.random(1,2) == 1 then
pos.x = pos.x + s[math.random(#s)]
else
pos.y = pos.y + s[math.random(#s)]
end
doTeleportThing(cid, getClosestFreeTile(cid, pos))
doCreatureSetStorage(cid, cid, 0)
addEvent(function(cid) if isCreature(cid) and getCreatureTarget(cid) ~= 0 and getCreatureStorage(getCreatureTarget(cid), cid) == -1 then doCreatureSetStorage(cid, cid, -1) end end, 1000, cid)
end
else
if getCreatureSpeed(cid) == 0 then
doChangeSpeed(cid, getCreatureBaseSpeed(cid))
end
end
elseif isSummon(target) and getPlayerStorageValue(getCreatureMaster(target), cid) == -1 then
if getCreatureSpeed(cid) == 0 then
doChangeSpeed(cid, getCreatureBaseSpeed(cid))
end
doPlayerSetStorageValue(getCreatureMaster(target), cid, 0)
doMonsterChangeTarget(cid)
end
else
if getCreatureSpeed(cid) == 0 then
doChangeSpeed(cid, getCreatureBaseSpeed(cid))
end
end
if #targets > 0 then
for k, v in ipairs(targets) do
if getDistanceBetween(getCreaturePosition(cid), getCreaturePosition(v)) <= distance then
if isPlayer(v) and getPlayerStorageValue(v, cid) == -1 then
doPlayerSetStorageValue(v, cid, 0)
elseif isSummon(v) and getPlayerStorageValue(getCreatureMaster(v), cid) == -1 then
doPlayerSetStorageValue(getCreatureMaster(v), cid, 0)
end
if getCreatureSpeed(cid) == 0 then
doChangeSpeed(cid, getCreatureBaseSpeed(cid))
end
else
if isPlayer(v) and getPlayerStorageValue(v, cid) == 0 then
if getCreatureSpeed(cid) == 0 then
doChangeSpeed(cid, getCreatureBaseSpeed(cid))
end
elseif isSummon(v) and getPlayerStorageValue(getCreatureMaster(v), cid) == 0 then
if getCreatureSpeed(cid) == 0 then
doChangeSpeed(cid, getCreatureBaseSpeed(cid))
end
end
end
end
else
if getCreatureSpeed(cid) == 0 then
doChangeSpeed(cid, getCreatureBaseSpeed(cid))
end
end
end
return true
end
PHP:
<event type="think" name="Thinks" event="script" value="Think.lua"/>
<event type="kill" name="Killss" event="script" value="Combat.lua"/>
PHP:
registerCreatureEvent(cid, 'Killss')
Ko?czymy w?dr?wk? po tym folderze i kierujemy si? do data/lib/050-function.lua i wklejamy tam:
PHP:
function isSummon(cid)
return getCreatureMaster(cid) ~= cid or false
end
Do config.lua dodajemy:
PHP:
distanceBetweenPlayerAndMonster = 2
Teraz folder monsters
Do ka?dego potwora, kt?rego trzeba sprowokowa? dodajemy (pod </flags>):
PHP:
<script>
<event name="Combats"/>
<event name="Thinks"/>
</script>
Z ka?dego takowego potwora usuwamy ataki (poza fizycznym i conditionami), na przyk?adzie Son of Verminor:
PHP:
<?xml version="1.0" encoding="UTF-8"?>
<monster name="son of verminor" nameDescription="son of verminor" race="venom" experience="5900" speed="240">
<health now="8500" max="8500"/>
<look type="19" corpse="1496"/>
<targetchange interval="5000" chance="10"/>
<strategy attack="100" defense="0"/>
<flags>
<flag attackable="1"/>
<flag hostile="1"/>
<flag convinceable="1"/>
<flag canpushitems="1"/>
<flag canpushcreatures="1"/>
<flag targetdistance="1"/>
<flag staticattack="90"/>
<flag runonhealth="0"/>
</flags>
<script>
<event name="Combats"/>
<event name="Thinks"/>
</script>
<attacks>
<attack name="melee" interval="2000" skill="155" attack="50" poison="-200"/>
<attack name="Square" interval="1031" target="0"/>
<attack name="SoV" interval="1006" target="0"/>
<attack name="poison" interval="1012" chance="12" range="1" min="-150" max="-200">
<attribute key="areaEffect" value="greenbubble"/>
<attribute key="shootEffect" value="poison"/>
</attack>
</attacks>
<defenses armor="35" defense="40" >
<defense name="outfit" interval="1052" chance="12" monster="rat" duration="4000">
<attribute key="areaEffect" value="redshimmer"/>
</defense>
<defense name="outfit" interval="1065" chance="12" monster="larva" duration="4000">
<attribute key="areaEffect" value="redshimmer"/>
</defense>
<defense name="outfit" interval="1016" chance="12" monster="scorpion" duration="4000">
<attribute key="areaEffect" value="redshimmer"/>
</defense>
</defenses>
<elements>
<element firePercent="10"/>
<element energyPercent="20"/>
</elements>
<immunities>
<immunity earth="1"/>
<immunity paralyze="1"/>
<immunity invisible="1"/>
<immunity lifedrain="1"/>
</immunities>
</monster>
PHP:
local config = {
['son of verminor'] = {ch = 11, c = COMBAT_DEATHDAMAGE, min = -220, max = -270, e = CONST_ME_SMALLCLOUDS},
['carniphila'] = {ch = 11, c = COMBAT_EARTHDAMAGE, min = -40, max = -130, e = CONST_ME_POISONAREA},
['infernalist'] = {ch = 14, ef = CONST_ANI_ENERGYBALL, c = COMBAT_MANADRAIN, min = -53, max = -120, e = CONST_ME_TELEPORT}
}
function onTargetTile(cid, pos)
local v = config[getCreatureName(cid):lower()]
pos.stackpos = STACKPOS_TOP_CREATURE
local creature = getThingFromPos(pos).uid
if v and isCreature(getCreatureTarget(cid)) then
if isPlayer(getCreatureTarget(cid)) and getPlayerStorageValue(getCreatureTarget(cid), cid) ~= -1 then
doSendMagicEffect(pos, v.e)
elseif isMonster(getCreatureTarget(cid)) then
doSendMagicEffect(pos, v.e)
end
if isPlayer(creature) and getPlayerStorageValue(creature, cid) ~= -1 then
doSendMagicEffect(pos, v.e)
if v.c == COMBAT_MANADRAIN then
doTargetCombatMana(cid, creature, v.min, v.max, v.e)
doSendDistanceShoot(getCreaturePosition(cid), getCreaturePosition(getCreatureTarget(cid)), v.ef)
else
doTargetCombatHealth(cid, creature, v.c, v.min, v.max, v.e)
end
elseif isMonster(creature) and creature ~= cid then
doSendMagicEffect(pos, v.e)
if v.c == COMBAT_MANADRAIN then
doTargetCombatMana(cid, creature, v.min, v.max, v.e)
doSendDistanceShoot(getCreaturePosition(cid), getCreaturePosition(getCreatureTarget(cid)), v.ef)
else
doTargetCombatHealth(cid, creature, v.c, v.min, v.max, v.e)
end
end
end
end
local combat = createCombatObject()
local area = createCombatArea(AREA_SQUARE1X1)
setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile")
setCombatArea(combat, area)
function onCastSpell(cid, var)
local v = config[getCreatureName(cid):lower()]
if math.random(100) <= v.ch then
if math.random(100000) <= 5000 then v.ch = v.ch + 1 end
return doCombat(cid, combat, var)
end
return true
end
PHP:
local config = {
['son of verminor'] = {ch = 14, c = COMBAT_POISONDAMAGE, min = -350, max = -390, e = CONST_ME_POISONAREA}
}
function onTargetTile(cid, pos)
local v = config[getCreatureName(cid):lower()]
pos.stackpos = STACKPOS_TOP_CREATURE
local creature = getThingFromPos(pos).uid
if v and isCreature(getCreatureTarget(cid)) then
if isPlayer(getCreatureTarget(cid)) and getPlayerStorageValue(getCreatureTarget(cid), cid) ~= -1 then
doSendMagicEffect(pos, v.e)
elseif isMonster(getCreatureTarget(cid)) then
doSendMagicEffect(pos, v.e)
end
if isPlayer(creature) and getPlayerStorageValue(creature, cid) ~= -1 then
doTargetCombatHealth(cid, creature, v.c, v.min, v.max, v.e)
elseif isMonster(creature) and creature ~= cid then
doTargetCombatHealth(cid, creature, v.c, v.min, v.max, v.e)
end
end
end
local combat = createCombatObject()
local area = createCombatArea(AREA_SQUARE1X1)
setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile")
setCombatArea(combat, area)
function onCastSpell(cid, var)
local v = config[getCreatureName(cid):lower()]
if math.random(100) <= v.ch then
if math.random(100000) <= 5000 then v.ch = v.ch + 1 end
return doCombat(cid, combat, var)
end
return true
end
PHP:
<instant name="Square" words="Square" selftarget="1" event="script" value="Monster_Attacks/square.lua"/>
<instant name="SoV" words="SoV" selftarget="1" event="script" value="Monster_Attacks/SoV.lua"/>
To tylko na przyk?adzie Son of Verminor, dla ka?dego potwora trzeba niestety robi? nowe czary (uroki LUA), dlaczego? Ano dlatego, ?e zwracaj?c false w funkcji onCombat potw?r i tak u?ywa czar?w.
Skrypt wymaga optymalizacji, nie testowa?em na wi?kszej ilo?ci potwor?w ani?eli ~40 naraz.