RE: @hitcheck - Rizz - 09-22-2014 09:29 PM
(09-22-2014 08:48 PM)Extreme Wrote: The new combat system can do that @hitcheck
I know that but when i tried to run it i got so many errors; maybe you should give us the possibility to use @hitcheck without call manually all the triggers.
In this way i could use the first code i posted.
RE: @hitcheck - XuN - 09-23-2014 01:04 AM
If you have more errors, post here to fix them instead of trying to get rid of the trigger, don't you think? 
Anyway, allowing other triggers to take place will make useless this one ... to do so just don't use this trigger and use the old behaviour, also ... fulltrigger were specially created for this situations, to simulate default trigger calls ... so it makes no sense to me as the idea is the correct, maybe there are some missing functions or so ... but fixing them seems to be better IMO.
RE: @hitcheck - Rizz - 09-23-2014 07:23 AM
PHP Code:
23:22:(sphere_combat.scp,28)combat_hit Dee 23:22:ERROR:(sphere_combat.scp,54)Undefined symbol 'throwing' 23:22:ERROR:(sphere_combat.scp,928)Undefined symbol 'throwing' 23:22:ERROR:(sphere_combat.scp,102)Undefined symbol '' 23:22:ERROR:(sphere_combat.scp,102)Undefined symbol 'local' 23:22:ERROR:(sphere_combat.scp,131)Can't resolve <tdata3> 23:22:ERROR:(sphere_combat.scp,919)Can't resolve <tdata3> 23:22:ERROR:(sphere_combat.scp,181)Undefined symbol '' 23:22:ERROR:(sphere_combat.scp,181)Undefined symbol 'qval' 23:22:(sphere_combat.scp,28)combat_hit Dee 23:22:ERROR:(sphere_combat.scp,54)Undefined symbol 'throwing' 23:22:ERROR:(sphere_combat.scp,928)Undefined symbol 'throwing' 23:22:ERROR:(sphere_combat.scp,102)Undefined symbol '' 23:22:ERROR:(sphere_combat.scp,102)Undefined symbol 'local'
The script i have (different from the starndard one bcuz i added max/min function):
Code:
//****************************************************************************
// SPHERE by : Menasoft ©1997-2014
// www.sphereserver.net
// All SPHERE script files and formats are copyright Menasoft & Partners.
// This file may be freely edited for personal use, but may not be distributed
// in whole or in part, in any format without express written permission from
// Menasoft & Partners. All donations and contributions
// become the property of Menasoft & Partners.
//****************************************************************************
// FILE LAST UPDATED: Saturday, August 2nd, 2014
//
VERSION=0.56c
[EVENTS e_combat_system]
ON=@HitCheck
call f_combat_hit <src>
src.f_combat_gethit=<local.dam>,<argn2>
[function f_combat_hit] // We get the hit state.
if (<src.IsItem>) // This should not happen, but I cannot hit items.
return -1
endif
if !(<src> || <src>==<uid> ) // I cannot hit the 'air' or myself.
return -1
endif
// I cannot damage if I'm dead, stoned, freezed or sleeping, same if the target is dead, invul o stoned or has less than 1 hit point (this last should not happen ... just a safecheck).
serv.log combat_hit <name>
if ( (<flags>&statf_dead) || (<flags>&statf_stone) || (<flags>&statf_freeze) || (<flags>&statf_sleeping) || (<src.flags>&statf_dead) || (<src.flags>&statf_invul) || (<src.flags>&statf_stone ) || <src.hits> < 1 ) )
return -1
endif
if (<region.safe> || <src.region.safe>) // I cannot hit if my region is safe or the target is on a safe region...
return -1
endif
if (<region.nopvp> || <src.region.nopvp>) // ... same for nopvp regions.
if ((<memoryfindtype.memory_ipet.link.isplayer> || <isplayer>) && (<src.memoryfindtype.memory_ipet.link.isplayer> || <src.isplayer>) )
return -1
endif
endif
local.dist=<src.distance> // Storing the distance between me and my target.
if (<local.dist>> 31) // if Distance > Radar view distance.
if (<serv.CombatFlags>&0200 || <Swing>!=SWING_SWINGING) // 0200 = COMBAT_STAYINRANGE.
return -1 // If Combat_StayInRange is not set and our swing state != preparing. Stop.
endif
endif
if (!<serv.CombatFlags>&040 && <region.flags>®ion_flag_ship) // 040 = AllowHitFromShip. If not Combat_AllowHitFromShip and my region is a ship.
if (<region.uid>!=<src.region.uid>) // and target's region is not mine ( hence i'm hitting outside the ship)...
sysmessage <defmsg.COMBAT_OUTSIDESHIP> // Stop.
return -1
endif
endif
if (<CanSee <src>>) // If I can see my target.
// And my target is being ridden (should not happen) or ! CanSeeLos (Ignoring windows if i'm shooting).
if ( (<src.brain> && <src.flags>&statf_ridden) || !<CanSeeLosFlag <src>,<qval ( <Action>==archery || <action>==throwing )? LOS_NB_WINDOWS : 0>>)
if ( !<serv.CombatFlags>&200 || <Swing>!=SWING_SWINGING) // I'm going to stop (unless i'm preparing to hit and Combat_StayInRange is not set).
argn1 SWING_READY
return 1
endif
argn1 SWING_EQUIPPING
return 1
endif
else
if ( !<serv.CombatFlags>&200 || <Swing>!=SWING_SWINGING) // same here but without LOS check.
argn1 SWING_READY
return 1
endif
argn1 SWING_EQUIPPING
return 1
endif
if ( (<brain>==brain_guard) && (<src.flags>&statf_conjured) ) // I'm a Guard, don't waste my time with stupid summons!!!
src.remove
argn1 SWING_EQUIPPING
return 1
endif
if ( (<serv.CombatFlags>&02) && <isplayer>) // 02 = COMBAT_FACECOMBAT. If I must face in combat and I'm a player (so NPCS doesn't have to face).
local.dir=<dir <src>>
if ( <local.dir> != <dir> && <local.dir> != (<dir>-1) && <local.dir> !=(<dir>+1) ) // Check if I'm looking to the target or dir = dir +1 || dir -1 ( Vision angle ).
argn1 SWING_READY
return 1
endif
endif
argn2=dam_physical // Creating argn2: dam_flags
if (<weapon>)
if (<weapon.tag0.override.damagetype>) // IF my weapon has special dmg flags ...
argn2 = <weapon.tag.override.damagetype> // I use them.
elseif ( <weapon.type>==t_weapon_sword || <weapon.type>==t_weapon_axe || <weapon.type>==t_weapon_throwing )
argn2 |=dam_slash // Setting flag for these weapons
elseif ( <weapon.type>==t_weapon_fence || <weapon.type>==t_weapon_bow || <weapon.type>==t_weapon_xbow )
argn2 |=dam_pierce // Same here
endif
if (<IsSkillRanged <action>>) // If my action is a ranged one ( Archery or Throwing ).
local.mindist=<qval <weapon.rangel> ? <weapon.rangel> : -1 > // Storing the min possible distance.
local.maxdist=<qval <weapon.rangeh> ? <weapon.rangeh> : -1 > // Storing the max possible distance.
if (<local.mindist> < 0) // If stored distance doesn't meet a min required we use the default's standard.
local.mindist = <serv.ArcheryMinDist>
endif
if (<local.maxdist> < 1 ) // Same for max distance.
local.maxdist = <serv.ArcheryMaxDist>
endif
if ( <local.dist> > <local.maxdist ) // If my target is far than my weapon's max distance...
if ( !<serv.CombatFlags>&200 || <Swing>!=SWING_SWINGING) // and I'm not preparing to hit or not Combat_StayInRange
argn1 SWING_READY
return 1
endif
argn1 SWING_EQUIPPING
return 1
endif
if (<flags>&statf_hasshield) // This should never happen, just a safecheck.
sysmessage=<defmsg.ITEMUSE_BOW_SHIELD>
action=0
argn1 -1
return 1
endif
if ( <local.dist> < <local.mindist> )
sysmessage=<defmsg.COMBAT_ARCH_TOOCLOSE> // I am so close to shoot a hit, stop.
anim=9
argn1 SWING_EQUIPPING
return 1
endif
if !(<isgm>)
reveal -1 // I reveal myself if i'm not GM.
endif
if !(<serv.CombatFlags>&01) // COMBAT_NODIRCHANGE
face <src> // If no COMBAT_NoDirChange I face the enemy.
endif
local.ammotype = <qval <weapon.ammotype> ? <weapon.ammotype> : <fixedid <tdata3>> // Setting the ammo id we are going to use, if the weapon doesn't have one specified with AmmoType we use TDATA3
if (<def0.<local.ammotype>>) // If arrow exist then we perform checks, if not ... weapon doesn't require ammo.
local.cont=<qval <weapon.ammocont> ? <weapon.ammocont> : <uid> > // AmmoCont is used here to set the container for the ammo.
ref200=<findcont.<local.cont>.findid.<local.ammotype>> // Store the ammo UID if any.
if (!<ref200>) // Check if there's ammo
if (<isplayer>) // If I'm a player and I don't have ammo: stop
sysmessage=<defmsg.COMBAT_ARCH_NOAMMO>
action=0
return -1
// else // Uncommenting these 2 lines will make npcs stop using ranged skills if they don't have ammo.
// return -1
endif
endif
endif
if ( <argn1> == SWING_READY )
if ( <local.dist> > <local.maxdist> )
argn1 SWING_READY
return 1
endif
if !(<IsGM>)
reveal
endif
if !(<serv.CombatFlags>&01) //COMBAT_NoDirChange
face <src>
endif
local.time = <GetWeaponSwingTimer>
argn1=<local.time>
FullTrigger @HitTry // I force the trigger and using call will make sure that code is stopped if there's a return in the trigger.
if (<local.return> == 1)
return -1
endif
local.time = <argn1>
argn1 = SWING_SWINGING
tag.fight_moved=0
if (<serv.CombatFlags>&04) //Combat_PreHit
tag.lasthit = <local.time> + <serv.time>
anim 9
timerd = 1
else
timerd = <local.time> / 2
anim 9 // ,<local.time>/10
endif
return 1
endif
//BEGIN HIT
local.color=<qval <weapon.ammoanimhue> ? <weapon.ammoanimhue> : <ref200.color> > // I use color stored in weapon, if any, or the ammo one.
local.anim=<qval <weapon.ammoanim> ? <weapon.ammoanim> : <weapon.tdata4> > // I use the animation of weapon.AmmoAnim or the default in TDATA4.
local.render=<qval <weapon.ammoanimrender> ? <weapon.ammoanimrender> ? 0 > // If my weapon have some special AmmoAnimRender I use it.
if (<local.ammotype>) // If I had ammo to use...
serv.newdupe <ref200>
new.attr |= attr_invis
new.timerf 20,remove
new.cont=<findlayer.21>
local.arrow=<new>
consume 1 <ref200.baseid> // I consume it.
endif
src.effect 0,<local.anim>,5,16,0,<local.color>,<local.render> // I shoot the 'arrow'
argn1 SWING_EQUIPPING
return 0
else // Not ranged skill
if ( <serv.CombatFlags>&04 && <Swing>==SWING_READY )
local.diff = <tag0.lasthit> - <serv.time>
if (<local.diff> > 0)
local.diff = <qval <local.diff> > 50 ? 50 : <local.diff> >
timerd = <local.diff>
argn1 SWING_READY
return 1
endif
endif
local.mindist = <weapon.rangel>
local.maxdist = <max <range>,<weapon.rangeh>>
if ( <local.dist> < <local.mindist> || <local.dist> > <local.maxdist> )
if ( !<serv.CombatFlags>&0200 || <swing>!=SWING_SWINGING )
argn1 SWING_READY
return 1
endif
argn1 SWING_EQUIPPING
return 1
endif
if ( <swing> == SWING_READY )
if ( <local.dist> > <local.maxdist> )
argn1 SWING_READY
return 1
endif
if !(<IsGM>)
reveal
endif
if !(<serv.CombatFlags>&01) //COMBAT_NoDirChange
face <src>
endif
local.time = <GetWeaponSwingTimer>
argn1=<local.time>
FullTrigger @HitTry // I force the trigger and using call will make sure that code is stopped if there's a return in the trigger.
if (<local.return>==1)
return -1
endif
local.time = <argn1>
swing = SWING_SWINGING
tag.fight_moved=0
if (<serv.CombatFlags>&04) //Combat_PreHit
tag.lasthit = <local.time> + <serv.time>
anim 9
timerd = 1
else
timerd = <local.time> / 2
anim 9 // ,<local.time>/10
endif
return 1
endif
if !(<serv.CombatFlags>&01) // COMBAT_NODIRCHANGE
face <src> // If no COMBAT_NoDirChange I face the enemy.
endif
if !(<IsGM>)
reveal
endif
endif
swing = SWING_SWINGING
tag.fight_moved = 0
local.time = <getswingtimer>
timerd = <local.time> / 2
local.weight = <min <qval <weapon> ? <weapon.weight> : 1 >, 10 >
stam -=<local.weight>
if ( <ActDiff> < 0 )
local.sound_miss = <qval <weapon.tag0.override.sound_miss> ? <weapon.tag.override.sound_miss> : 0 >
argo = <weapon>
FullTrigger @HitMiss
if (<local.return>==1)
return -1
endif
endif
if ( <ActDiff> < 0 ) // Calling it again in case the trigger had change it.
if ( <IsSkillRanged <action> > )
local.sound = <qval <local.sound> ? <local.sound> : <qval <r0,1>==1 ? 0233 : 0238 > >
sound = <local.sound>
if ( <local.arrow> )
ref10=<local.arrow>
if ( <r5> )
ref10.attr &=~attr_invis
ref10.p=<src.p>
else
ref10.remove
endif
endif
argn1 SWING_EQUIPPING
return 1
endif
local.sound = <qval <local.sound> ? <local.sound> : <eval { 0238 1, 0239 1, 023a 1} > >
sound = <local.sound>
if (<detail>)
sysmessagef="<defmsg.COMBAT_MISSS>",<src.name>
endif
if (<src.detail>)
src.sysmessagef="<defmsg.COMBAT_MISSO>",<name>
endif
argn1 SWING_EQUIPPING
return 1
endif
if ( <src.action> == healing )
src.action -1
src.sysmessage=<defmsg.HEALING_INTERRUPT>
endif
local.dam=<CalcDamage 0>
local.swing=<argn1>
argn1=<action>
FullTrigger @SkillSuccess
//SkillTrigger @Success
argn1=<local.dam>
fulltrigger @Hit
argn2 |=DAM_FIXED // Damage has been properly set, no need of default checks so DAM_FIXED make Sphere skip internal checks.
if (<local.return>==1)
return -1
endif
if ( <local.arrow> && <r2> ) // Small chance for the arrow to be placed in backpack instead of the ground
src.bounce <local.arrow>
endif
if ( !<src.region.nopvp> && !<IsPlayer> && ! <src.IsPlayer> )
SkillUseQuick <action>
endif
if ( <local.sound> > 0 )
sound = <local.sound>
endif
if ( <weapon> )
if ( <weapon.morex> == 20 ) // Poisoned weapon
if ( <r100> < <weapon.morez> )
local.poison = <r<weapon.morez>>
src.SetPoison <eval <local.poison> * 10 >,<eval <local.poison> / 5>, <uid>
weapon.more -= <local.poison>
weapon.resendtooltip
endif
weapon.damage=<eval <local.dam> / 4 >,<src>
endif
else
if ( <brain> == BRAIN_MONSTER && <poisoning> > 30.0 && <r100> < <poisoning> )
src.SetPoison <r<poisoning>>, <r<poisoning>/50>,<uid>
endif
endif
src.skillgain <argn1>,<actdiff>
endif
[function max]
local.ret=0
for 0 <eval <argv>-1>
if (<argv[<dlocal._for>]>><local.ret>)
local.ret <argv[<dlocal._for>]>
endif
endfor
return <dlocal.ret>
[function min]
local.ret=<argv[0]>
for 0 <eval <argv>-1>
if (<argv[<dlocal._for>]><<local.ret>)
local.ret <argv[<dlocal._for>]>
endif
endfor
return <dlocal.ret>
[function GetWeaponSwingTimer]
if ( <weapon> )
local.speed=<qval <tag0.override.speed> ? <tag.override.speed> : <weapon.speed> >
if ( <local.speed> )
local.waittime = <eval (<serv.SpeedScaleFactor> * 10 ) / (<max <dex>+100,1> * <local.speed>)>
return <qval <local.waittime> > 5 ?5:<dlocal.waittime>>
endif
endif
if (<brain>==brain_guard)
return 1
endif
// Base speed is just your DEX range=40 to 0
local.waittime = <muldiv (100-<dex>),40,100>
if ( <local.waittime> < 5 ) // no-one needs to be this fast.
local.waittime = 5
else
local.waittime +=5 // why this 'free' increase of wait time?
endif
// Speed also effected by strength
// This is only reached if weapon.speed = 0 and !weapon.tag.override.speed, correct?
if (<weapon>)
local.weaponwait = (<weapon.weight>*10) / 40
if (<weapon.twohands>)// 2 handed is slower
local.weaponwait += <local.waittime>/2
endif
else
local.waittime +=2
endif
return <dlocal.waittime>
[function SetPoison]
// argn1 = Poison strenght
// argn2 = duration
// argn3 = src
if ( <flags>&statf_conjured ) // No poison for conjured creatures.
return 0
endif
if ( <flags>&statf_poisoned ) // If already poisoned, charges get updated (but not strenght)
findid.i_rune_poison.more2 += <argv2>
return 0
endif
sysmessage=<defmsg.JUST_BEEN_POISONED>
if ( <flags>&statf_freeze )
flags &=~statf_freeze
endif
spelleffect s_poison,<argv1>,<argv3>
new.more2=<argv2>
return 1
[function f_combat_gethit] // GetHit
if (<flags>&statf_invul)
effect 3,14265,9,30
return 1
elseif (<flags>&statf_stone)
effect 3,14265,9,30
return 1
elseif (<region.safe>)
effect 3,14265,9,30
return 1
elseif ( (<region.nopvp>) && ((<src.IsPlayer>) || (<src.memoryfindtype.memory_ipet.link.isplayer>)) )
effect 3,14265,9,30
return 1
elseif (<flags>&statf_dead)
return 1
endif
local.dam=<argn1>
if (<serv.CombatFlags>&00008) // Combat_Use_Resistance
if (<argn2>&dam_physical)
local.damcount ++
endif
if (<argn2>&dam_pierce)
local.damcount ++
endif
if (<argn2>&dam_slash)
local.damcount ++
endif
if (<argn2>&dam_poison)
local.damcount ++
local.temppoison ++
endif
if (<argn2>&dam_lightning)
local.damcount ++
local.tempenergy ++
endif
if (<argn2>&dam_cold)
local.damcount ++
local.tempcold ++
endif
if (<argn2>&dam_fire)
//if (<serv.chardef.<baseid>.can>&mt_fire_immune) // Old check, can is also stored in dynamic characters, not only chardef.
if ( <can>&mt_fire_immune )
if !( <argn2>& DAM_PHYSICAL || <argn2>& DAM_PIERCE || <argn2>& DAM_SLASH || <argn2>& DAM_POISON || <argn2>& DAM_ENERGY || <argn2>& DAM_COLD ) // if the damage type is fire only
return 1 // no dmg
endif
// local.dmg /=2 // this is the default code
local.tmpfire = 0 // but this makes more sense.
else
local.damcount ++
local.tempfire ++
endif
endif
if (<local.damcount>==7) // if all damages are present, bonus dmg.
local.damcount ++
endif
local.temppoison *= <argn> / <local.damcount>
local.tempfire *= <argn> / <local.damcount>
local.tempcold *= <argn> / <local.damcount>
local.tempenergy *= <argn> / <local.damcount>
if ( (<local.temppoison>+<local.tempfire>+<local.tempcold>+<local.tempenergy>) < <local.dam> )
local.dam -= (<local.temppoison>+<local.tempfire>+<local.tempcold>+<local.tempenergy>)
else
local.dam = 0
endif
local.fire +=<local.tempfire>
local.cold +=<local.tempcold>
local.energy +=<local.tempenergy>
local.poison +=<local.temppoison>
endif
local.fire -= <muldiv <local.fire>,<resfire>,100>
local.cold -= <muldiv <local.cold>,<rescold>,100>
local.energy -= <muldiv <local.energy>,<resenergy>,100>
local.poison -= <muldiv <local.poison>,<respoison>,100>
if (<local.dam> < 0 && <local.fire> < 0 && <local.cold> < 0 && <local.energy>< 0 && <local.poison>< 0 )
return 1
endif
if ( <src.Weapon> && <serv.CombatFlags>&00080 && (<argn2>&DAM_PHYSICAL || <argn2>&DAM_PIERCE || <argn2>&DAM_SLASH)) ) // COMBAT_OSIDAMAGEMOD
local.mod = 0
local.modtemp = 0
// Begin bonus section
if ( <src.weapon.type>==t_weapon_axe || <weapon.type>==t_weapon_sword )
local.modtemp = <src.lumberjacking>/50
if (<src.lumberjacking> > 100.0)
local.modtemp +=10
endif
endif
local.mod +=<local.modtemp>
local.modtemp=<src.tactics>/16
if (<src.tactics>> 100.0)
local.modtemp +=6
endif
local.mod +=<local.modtemp>
local.modtemp=<src.anatomy>/16
if (<src.anatomy>> 100.0)
local.modtemp +=5
endif
local.mod += <local.modtemp>
local.modtemp=<src.str>/3
if (<src.str> > 100 )
local.modtemp += 5
endif
local.mod += <local.modtemp>
local.dam += <local.dam> * (<local.mod>/100) // local.dam += <local.dam> * current bonus /100
// End bonus section
endif
local.dam = <local.dam> + <local.fire> + <local.energy> + <local.cold> + <local.poison>
argn1=<local.dam>
FullTrigger @GetHit
if (<local.return> == 1)
return 1
endif
if ( (<argn2>&dam_energy || <argn2>&dam_physical || <argn2>&dam_fire || <argn2>&dam_pierce || <argn2>&dam_slash || <argn2>&dam_magic ) && !(<argn2>&dam_nounparalyze))
if (<flags>&statf_freeze)
findid.i_rune_paralyze.remove
endif
endif
if ( <argn2>&dam_physical || <argn2>&dam_pierce || <argn2>&dam_slash) )
if (<flags>&statf_hidden)
flags &= ~statf_hidden
endif
if ( (<flags>&statf_reactive) && !(<argn2>&dam_god) )
if !( (<src> == <uid>) || (<src.brain>==brain_guard) || (<distance> > 2) ) // We shouldn't reflect dmg to ourselves or guards or targets with distance > 2
local.effect=<f_value_getlinear <magery>,100.0,<serv.spell.s_reactive_armor.effect>> // We asume max magery skill = 100.0
endif
local.effect=<medium <0,<local.effect>,(<local.dam>-1)>
// make sure the reflected damage is between 0 and local.Dam-1 or else
// 2 reactive armour users could get caught in an infinite loop of
// reflecting damage
if (<local.effect> > 0)
local.dam -=<local.effect>
src.damage <local.effect>,<uid>,<argn2>
TRYSRC <src> effect 3,14154,9,6
endif
endif
//armor calculations
if !(<argn2>&dam_god)
if !(<argn2>&dam_general)
local.armor=<r<max (<armor>+<modar>),0>>
local.dmg=<OnTakeDmg <local.dam>,<src>,<argn2>> // fixme iDmg = OnTakeDamageHitPoint( iDmg, pSrc, uType );
if (<serv.MagicFlags>&04) // MAGICF_IGNOREAR
local.armor = 0
else
local.armor /=2
endif
local.dmg -= <local.armor>
elseif !(<serv.MagicFlags>&04 || <argn2>&dam_magic)
local.dmg -=<r<<armor>+<serv.chardef.<baseid>.armor>>>
endif
endif
endif
//FixMe
// from here i'll add DAM_FIXED so the sphere itself handles the rest of code, which not all can be scriptable right now (the parts with FIXME)
// FIXME src.AttackedBy <uid>
// local.id=<attacker.id <src>>
// if !( <local.id>)
// attacker.add <src>
// local.id=<attacker.id <src>>
// endif
// attacker.<dlocal.id>.dam += <local.dam>
// attacker.<dlocal.id>.elapsed = 0
// attacker.<dlocal.id>.threat += <local.dam>
// if (<local.dam> > 10 )
// local.blood=<r4650,4655>
// elseif (<r<local.dam>> > 5)
// local.blood=5701
// endif
// if ( (<local.blood> && (<argn2>&dam_pierce || <argn2>&dam_slash) && !(<flags>&statf_conjured) )
// serv.newitem=<local.blood>
// new.attr=attr_decay|attr_move_never
// new.timer=7
// endif
// hits -= <local.dam>
// anim = 20
//fixme add/remove/update memorys
//fixme @Death/@DeathCorpse + @Kill triggers
// return 1
argn2 |=dam_fixed
[function OnTakeDmg]
// This function is called when every check is already done, the damage is calculated and the dam is going to come.
// The body part which is going to be hit is checked in this function.
// Deflect some damage with shield or weapon ?
if !( <argv2>&DAM_GENERAL )
return <argv0>
endif
local.dam=<argv0>
if ( ( <flags>&STATF_HASSHIELD ) && ( ( <argv2>&DAM_PHYSICAL ) || ( <argv2>&DAM_PIERCE ) || ( <argv2>&DAM_SLASH ) ) && !( ( <argv2>&DAM_GOD ) || ( <argv2>&DAM_ENERGY ) ) )
ref1=<findlayer.2>
if ( <ref1.type>==t_shield && <SkillUseQuick Parrying,<r<qval <src>!=<uid>? <src.tactics>/10:100>>> )
local.def=<r<ref1.Armor_GetDefense>/2>
local.hitscur=<ref1.hits>
ref1.damage=<min <local.dam>,<local.def>>,<argv1>,<argv2>
if ( <hits> < <local.hitscur> )
sysmessage = <defmsg.COMBAT_PARRY>
endif
local.dam -= <local.def>
endif
endif
if ( <can>&MT_NONHUM )
return <dlocal.dam>
endif
// Where was the hit ?
local.HitRoll = <r100> // determine area of body hit
local.HitArea = 0 // 0 = HEAD
local.HitPref = <qval <src.tag0.HitPreference> ?<src.tag.HitPreference>:0>
local.HitPrefChance = <qval <src.tag0.HitPreference_Chance>?<src.tag.HitPreference_Chance>:<src.tactics>>
local.HitPrefPenalty = <qval <src.tag0.HitPreference_Penalty>?<src.tag0.HitPreference_Penalty>:30> // Percent
local.HitPrefBonus = <qval <src.tag0.HitPreference_Bonus>?<src.tag0.HitPreference_Bonus>:30> // Percent
if ( ( <serv.CombatFlags>&02000 ) && ( <local.HitPref>!=0 ) && ( ( <argv2>&DAM_PHYSICAL ) || ( <argv2>&DAM_PIERCE ) || ( <argv2>&DAM_SLASH ) ) && !( ( <argv2>&DAM_GOD ) || ( <argv2>&DAM_ENERGY ) ) )
if (<r1100> < <local.HitPrefChance> )
while ( <local.HitPref> > 7 ) // Here the default body parts are used, if you are planing to extend it ... place a check for bodies, ie: if body == dragon, must be higher than 7 and lower than 14?
local.HitPref -= 7 // We lower it until we get a useable value.
end
local.HitArea=<local.HitPref>-1
local.dam += (<local.dam>*<local.HitPrefBonus>)/100
else
local.dam += (<local.dam>*<local.HitPrefPenalty>)/100
src.sysmessage=<defmsg.COMBAT_TARGET_MISSED>
while ( <local.hitarea> <= 7 && <local.hitroll> > 0 )
local.HitRoll -= <Armor_GetCoverageZone <local.hitarea>>
local.hitarea ++
end
endif
else
while ( <local.hitarea> <= 7 && <local.hitroll> > 0 )
local.HitRoll -= <Armor_GetCoverageZone <local.hitarea>>
local.hitarea ++
end
endif
if ( ( ( <argv2>&DAM_PHYSICAL ) || ( <argv2>&DAM_PIERCE ) || ( <argv2>&DAM_SLASH ) ) && !( ( <argv2>&DAM_GOD ) || ( <argv2>&DAM_ENERGY ) ) )
if ( <detail> || <src.detail> )
local.rMsg=<r3>
doswitch <local.hitarea>
local.tMsg=combat_hit_head
local.tMsg=combat_hit_neck
local.tMsg=combat_hit_back
local.tMsg=combat_hit_chest
local.tMsg=combat_hit_arms
local.tMsg=combat_hit_hands
local.tMsg=combat_hit_legs
local.tMsg=combat_hit_feet
enddo
if ( <argv0> > 10 && ( <local.hitarea>==ARMOR_HEAD || <local.hitarea>==ARMOR_CHEST ) )
local.rMsg +=3
endif
local.selfmsg=<local.tMsg><dlocal.rMsg>o
local.targmsg=<local.tMsg><dlocal.rMsg>s
if (<detail>)
sysmessagef=<defmsg.<local.selfmsg>>,<src.name>
endif
if (<src.detail>)
src.sysmessagef=<defmsg.<local.targmsg>>,<name>
endif
endif
endif
if ( ( <serv.MagicFlags>&04 ) && ( <argv2>&DAM_MAGIC ) ) //MAGICF_IGNOREAR. No need to check the following if we don't need it.
return <dlocal.dam>
endif
local.maxcoverage=0
for 0 24
ref1=<findlayer.<local._for>>
if (<ref1>)
if (<ref1.morex>)
if (<ref1.morex> == s_SteelSkin || <ref1.morex> == s_StoneSkin || <ref1.morex> == s_Arch_Prot || <ref1.morex> == s_Protection )
local.maxcoverage <max <local.maxcoverage>,<f_value_getlinear <morez>,<serv.skillclass.skillclass_undeclared.magery>,<serv.spell.<ref1.morex>.effect>> >
endif
endif
for zone 0 7
if (<ref1.armor_IsCoverageZone <local.zone>>)
if ( <serv.CombatFlags>&01000 ) // COMBAT_STACKARMOR
local.maxcoverage +=<ref1.armor_getdefense>
else
local.maxcoverage = <max <local.maxcoverage>,<ref1.armor_getdefense> >
endif
ref1.damage=<local.dam>,<argv1>,<argv2>
endif
endfor
endif
endfor
local.dam -=<r<local.maxcoverage>>
return <dlocal.dam>
[DEFNAME body_parts]
// These are the current hit parts.
ARMOR_HEAD = 0
ARMOR_NECK = 1
ARMOR_BACK = 2
ARMOR_CHEST = 3 // or thorax
ARMOR_ARMS = 4
ARMOR_HANDS = 5
ARMOR_LEGS = 6
ARMOR_FEET = 7
// Following ones are not being used, but can give some ideas for extending the actual hit system.
// BODYPART_LEGS2 =8 // Alternate set of legs (spider)
// BODYPART_TAIL =9 // Dragon, Snake, Alligator, etc. (tail attack?)
// BODYPART_WINGS =10 // Dragon, Mongbat, Gargoyle
// BODYPART_CLAWS =11 // can't wear any gloves here!
// BODYPART_HOOVES =12 // No shoes
// BODYPART_HORNS =13 // Bull, Daemon
// BODYPART_STALKS =14 // Gazer or Corpser
// BODYPART_BRANCHES =15 // Reaper.
// BODYPART_TRUNK =16 // Reaper.
// BODYPART_PSEUDOPOD =17 // Slime
// BODYPART_ABDOMEN =18 // Spider or insect. asusme throax and chest are the same.
[function Armor_GetCoverageZone]
if ( <argn>==ARMOR_BACK )
return <max <Armor_GetCoverageLayer LAYER_SHIRT,<argn>>,<Armor_GetCoverageLayer LAYER_CHEST,<argn>>,<Armor_GetCoverageLayer LAYER_TUNIC,<argn>>,<Armor_GetCoverageLayer LAYER_CAPE,<argn>>,<Armor_GetCoverageLayer LAYER_ROBE,<argn>>>
elseif ( <args> == ARMOR_FEET )
return <max <Armor_GetCoverageLayer LAYER_SHOES,<argn>>,<Armor_GetCoverageLayer LAYER_LEGS,<argn>>>
elseif ( <args> == ARMOR_LEGS )
return <max <Armor_GetCoverageLayer LAYER_PANTS,<argn>>,<Armor_GetCoverageLayer LAYER_SKIRT,<argn>>,<Armor_GetCoverageLayer LAYER_HALF_APRON,<argn>>,<Armor_GetCoverageLayer LAYER_ROBE,<argn>>,<Armor_GetCoverageLayer LAYER_LEGS,<argn>>>
elseif ( <args> == ARMOR_CHEST )
return <max <Armor_GetCoverageLayer LAYER_SHIRT,<argn>>,<Armor_GetCoverageLayer LAYER_CHEST,<argn>>,<Armor_GetCoverageLayer LAYER_TUNIC,<argn>>,<Armor_GetCoverageLayer LAYER_ROBE,<argn>>>
elseif ( <args> == ARMOR_NECK )
return <Armor_GetCoverageLayer LAYER_COLLAR,<argn>>
elseif ( <args> == ARMOR_ARMS )
return <max <Armor_GetCoverageLayer LAYER_ARMS,<argn>>,<Armor_GetCoverageLayer LAYER_ROBE,<argn>>,<Armor_GetCoverageLayer LAYER_CAPE,<argn>>>
elseif ( <args> == ARMOR_HANDS )
return <Armor_GetCoverageLayer LAYER_GLOVES,<argn>>
elseif ( <args> == ARMOR_HEAD )
return <Armor_GetCoverageLayer LAYER_HELM,<argn>>
endif
return 0
[function Armor_IsCoverageZone]
if ( <args> == ARMOR_BACK )
return <eval ( (<layer>==LAYER_SHIRT) || (<layer>==LAYER_CHEST) || (<layer>==LAYER_TUNIC) || (<layer>==LAYER_CAPE) || (<layer>==LAYER_ROBE))>
elseif ( <args> == ARMOR_FEET )
return <eval (<layer>==LAYER_SHOES || <layer>==LAYER_LEGS )>
elseif ( <args> == ARMOR_LEGS )
return <eval (<layer>==LAYER_PANTS || <layer>==LAYER_SKIRT || <layer>==LAYER_HALF_APRON || <layer>==LAYER_ROBE || <layer>==LAYER_LEGS)>
elseif ( <args> == ARMOR_CHEST )
return <eval (<layer>==LAYER_SHIRT || <layer>==LAYER_CHEST || <layer>==LAYER_TUNIC || <layer>==LAYER_ROBE )>
elseif ( <args> == ARMOR_NECK )
return <eval (<layer>==LAYER_COLLAR )>
elseif ( <args> == ARMOR_ARMS )
return <eval (<layer>==LAYER_ARMS || <layer>==LAYER_ROBE || <layer>==LAYER_CAPE )>
elseif ( <args> == ARMOR_HANDS )
return <eval (<layer>==LAYER_GLOVES )>
elseif ( <args> == ARMOR_HEAD )
return <eval (<layer>==LAYER_HELM )>
endif
return 0
[function Armor_GetCoverageLayer]
// Uncommenting the first line will make the system calc the percentaje of armor for armor + modar*GetcoveragePercent (body area),100 (Old Style) instead of ResPhysical when hitting body parts.
return <eval <findlayer.<argv0>.armor> +<findlayer.<argv0>.modar>>
// Here we have the % of armor coverage for each body zone
[function Armor_GetCoveragePercent]
if ( <argn>==ARMOR_BACK )
return <ddef.coverage_layer_back>
elseif ( <argn>==ARMOR_HEAD )
return <ddef.coverage_layer_head>
elseif ( <argn>==ARMOR_NECK )
return <ddef.coverage_layer_collar>
elseif ( <argn>==ARMOR_CHEST )
return <ddef.coverage_layer_chest>
elseif ( <argn>==ARMOR_ARMS )
return <ddef.coverage_layer_arms>
elseif ( <argn>==ARMOR_HANDS )
return <ddef.coverage_layer_gloves>
elseif ( <argn>==ARMOR_LEGS )
return <ddef.coverage_layer_legs>
elseif ( <argn>==ARMOR_FEET )
return <ddef.coverage_layer_feet>
endif
[DEFNAME armor_coverages]
coverage_layer_head=10
coverage_layer_neck=5
coverage_layer_back=10
coverage_layer_chest=30
coverage_layer_arms=10
coverage_layer_hands=10
coverage_layer_legs=20
coverage_layer_feet=5
[function Armor_GetDefense]
if !( <IsArmor> )
return 0
endif
local.val = <armor> + <modar>
local.repair = <GetRepairPercent>
local.val = <muldiv <local.val>,<local.repair>,100>
if ( <attr>&ATTR_MAGIC )
local.repair = <f_value_getlinear <morey>,<serv.skillclass.skillclass_undeclared.magery>,<serv.spell.s_enchant.effect>
local.val += <local.repair>
if ( <local.val> < 0 )
local.val = 0
endif
endif
return <dlocal.val>
[function medium]
return <qval <argv0>><argv1> ? <argv0> : <qval <argv2>< <argv1> ? <argv2> : <argv1>>>
[function f_value_getlinear]
// arg0 = actual value
// arg1 = max posible value
// arg2-5 = values to calculate
// example: <f_Value_GetLinear <magery>,<serv.skillclass.<skillclass>.magery>,<serv.spell.s_reactive_armor.effect>> will return the current value for your magery skill at this spell.
local.SegSize=0
local.LoIdx=0
local.skill=<argv0>
args=<streat <args>>
local.max=<argv0>
args=<streat <args>>
local.Qty = <argv>
doswitch <local.Qty>
return 0 // no values defined !
return <eval (<args>*<local.skill>)/<local.max>>
local.SegSize=1000
begin
if ( <local.skill> >= 500 )
local.LoIdx = 1
local.skill -= 500
endif
local.SegSize = 500
end
enddo
if (<local.qty>>3)
local.LoIdx = <MULDIV <local.skill>, <local.Qty>, 1000 >
local.Qty --
if ( <local.LoIdx> >= <local.Qty> )
local.LoIdx = <local.Qty> - 1
endif
iSegSize = 1000 / <local.Qty>
local.skill -= ( <local.LoIdx> * <local.SegSize> )
endif
local.LoVal = <argv<dlocal.LoIdx>>
local.HiVal = <argv<eval <local.LoIdx>+1>>
if (<local.HiVal> < <local.LoVal>)
local.HiVal = <local.LoVal>
endif
local.Chance = <local.LoVal> + <MULDIV <eval <local.HiVal> - <local.LoVal>>, <local.skill>, <local.SegSize> >
if ( <local.Chance> <= 0 )
return 0 // less than no chance ?
endif
return <dlocal.Chance>
[function CalcDamage]
// argn1 = 0 = normal damage.
// argn1 = 1 = random damage.
if ( <brain> == BRAIN_GUARD && <serv.GuardsInstantKill> )
return <src.maxhits> + 10000
endif
local.ret=1
if ( <serv.CombatFlags>&080 ) // Combat_OsiDamageMod
if ( <IsSkillRanged <action> > )
local.ret += <qval <argn1> == 1 ? <r<dex>> : <dex> > / 10
else
local.ret += <qval <argn1> == 1 ? <r<str>> : <str> > / 10
endif
endif
if ( <weapon> )
local.ret += <weapon.WeaponCalcDamage <argn1>>
else
local.ret += <dam.lo>
local.ret += <qval <argn1> == 1 ? <r<dam.hi>> : <dam.hi> >
endif
if ( <local.ret> < 0 )
local.ret = 0
endif
return <dlocal.ret>
[function WeaponCalcDamage]
local.ret=<dam.lo> + <modar>
local.ret += <qval <argn1> == 1 ? <r<dam.hi>> : <dam.hi> >
local.ret = <muldiv <local.ret>,<GetRepairPercent>,100>
if ( <attr>&attr_magic && !<type>==t_wand )
local.ret += <f_Value_GetLinear <more2>,<serv.skillclass.0.magery>,<serv.spell.s_enchant.effect>>
endif
if ( <local.ret> < 0 )
local.ret = 0
endif
return <dlocal.ret>
[function GetRepairPercent]
if ( !<MaxHits> || ( <MaxHits> < <Hits> ) )
return 100
endif
return <muldiv <hits>,100,<MaxHits> >
[function fixedid]
local.flags=<tdata3>
local.flags &=~0ffffffff9c000000
return <local.flags>
[function IsSkillRanged]
if !(<def0.<args>>)
return 0
endif
return <qval <args>==archery ? 1 : <qval <args>==throwing ? 1 : 0>>
[EOF]
I don't have the throwing skills.
Is this script 100% compatible with the normal behaviours?
I mean 100% compatible under every circumstances.
If i use this script should i move everything i scripted with hittry/hitmiss/hit/gethit/etc under @hitcheck?
I need to know which kind of timer GetWeaponSwingTimer is going to set, i will try to explain.
Code:
A B C D
|---------|----------------|---------|
swing wait time swing
I need a "swing" time (A-B, the time requested to start and finish the swing) set to 0.3 seconds ALWAYS.
I need to change "wait time" (B-C) based on my formula.
The formula is:
Code:
IF (<dex> <= 100)
LOCAL.delayarco=<FLOATVAL ((<dLOCAL.speedscalefactor>/((<dex> + 100)*<findlayer.2.speed>))+(4-0.04*<dex>))*10)>
ELIF ....
.....
GetWeaponSwingTimer is the time:
1) AB
2) BC
3) AC
I need to know.
Right now, my code using sphere_combat has no changes and this should be good (bcuz is the normal behaviour).
RE: @hitcheck - Rizz - 09-28-2014 12:39 AM
Anyone here? Xun?
|