Rizz
Master
Posts: 396
Likes Given: 21
Likes Received: 14 in 9 posts
Joined: Oct 2012
Reputation: 0
|
RE: @hitcheck
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).
(This post was last modified: 09-23-2014 07:50 AM by Rizz.)
|
|