rendered paste body[DEFNAME battlesystem_defs]
bts_weapon_parry_chance 10 //%
bts_weapon_absorb_chance 5 //%
[TYPEDEF t_status]
on=@DCLICK
Link=<src>
timerd 2
return 1
on=@Timer
if (<link.hits>!=<tag0.hits>)
tag0.hits=<link.hits>
say @1001,0,1 <Link.Hits>
endif
timerd 2
return 1
[EVENTS e_battlesystem]
on=@PersonalSpace
ARGN1=<eval ((<str>*5)/(<src.str>+((<src.dex>*3)/2)))+1>
IF (<ARGN1>><SRC.STAM>)
return 1
ENDIF
on=@Death
FORCONTTYPE T_SPELL 0
remove
ENDFOR
IF (<FINDLAYER.25.UID>)
flags=<flags>|statf_onhorse //Фикс для прилипающей хорсы
ENDIF
FORCHARMEMORYTYPE MEMORY_FIGHT //Фикс для @kill
COLOR |= <DEF.memory_harmedby>
ENDFOR
forchars 12
if (<npc>)
trigger @SeeDeath
endif
endfor
on=@Kill
if (<src.findlayer.1.isweapon>)
trysrc <argo> uid.<src>.findlayer.1.trigger @KillEnemy
elif (<findlayer.2.isweapon>)
trysrc <argo> uid.<src>.findlayer.2.trigger @KillEnemy
endif
return 0
on=@DeathCorpse
try uid.<argn1>.tag.resources=<tag.resources>
//Lootable AI
if (!<tag0.loot_protect>)
newitem im_corpse_looting_timer
new.link = <argo>
new.p = <argo.p>
new.timer = 1
endif
local.corpse=<argo>
if (<npc>)
forcont <findlayer.layer_bankbox> 1
cont = <local.corpse>
endfor
endif
on=@DCLICK
IF ((<SRC>==<UID>) && (<FINDLAYER.25.UID>))
flags=<flags>|statf_onhorse
ENDIF
on=@UserWarmode
IF (<ARGN1>)
FORCHARMEMORYTYPE MEMORY_WAR_TARG
REMOVE
ENDFOR
ENDIF
on=@HitTry
src.allperks_disable
//if (<ARGO.uid>)
// tag0.weap_perk=<TAG0.perk.prof_<ARGO.TAG.WEAPON_NAME>>
// tag0.e_weap_perk=<SRC.TAG0.perk.prof_<ARGO.TAG.WEAPON_NAME>>
//else
// tag0.weap_perk=<TAG0.perk.prof_wrestling>
// tag0.e_weap_perk=<SRC.TAG0.perk.prof_wrestling>
//endif
ACTDIFF=0
serv.log **** Swing Start ****
serv.log Weapon Speed = <ARGO.SPEED>
if (<argo>) //Для оружия
tag.hit_skill=<argo.skill>
//** TEMPORARY!
if (<tag.hit_skill>==-1)
add_error_log Invalid SKILL: <argo.name> : <argo.baseid> : <argo.uid>
tag.hit_skill=Tactics
endif
//**//
tag.hit_dam=<argo.dam>
argn1=<eval ((<ARGO.SPEED>/2) + (( (10000*<ARGO.SPEED>)/2) / (<DEX>*((<<tag.hit_skill>>/20)+500))))> //+++
else //Для кулаков
tag.hit_skill=wrestling
tag.hit_dam =<dam>
if (<tag0.speed>)
argn1=<eval ((<tag.speed>/2) + (( (10000*<tag.speed>)/2) / (<DEX>*((<<tag.hit_skill>>/20)+500)) ))> //+++
else
argn1=<eval ((<def.wrest_speed>/2) + (( (10000*<def.wrest_speed>)/2) / (<DEX>*((<<tag.hit_skill>>/20)+500)) ))> //+++
endif
endif
argn2=0
argn3=0
serv.log Final Speed = <argn1>
tag.hit_started=1
//argn1 = <eval (<argn1>*2)/3>
//HIT_DISTANCE_RESET <src> <argn1>
on=@Hit
serv.log **** Hit start ****
//Checking region flags
IF ((<SRC.REGION.FLAGS> & (REGION_FLAG_SAFE|REGION_FLAG_NO_PVP)) || (<SRC.FLAGS> & STATF_INVUL))
SRC.EFFECT 3, i_fx_glow, 3, 20, 1
return 1
ENDIF
//Deleting Arrows
IF (<ARGO.ISRANGED>)
consume 1 <argo.tag0.arrow_type>
ENDIF
//*** Подсчет шансов отразить и поглотить удар оружием и броней
if (<src.findlayer.2.type>==t_shield)
//Shield
serv.log <src.name> has a shield
local.parry_percent=<src.findlayer.2.tag.chance_parry>
local.absorb_percent=<src.findlayer.2.tag.chance_absorb>
local.parry_object = <src.findlayer.2>
elif (<ARGO.isranged>)
//У врага нету щита, а у нас лук.
serv.log <src.name> has no shield, but we have some arrows!
local.parry_percent=0
local.absorb_percent=0
local.parry_object=0
elif ((<src.findlayer.2.type>==<findlayer.2.type>) || (<src.findlayer.1.type>==<findlayer.1.type>))
//Same weapons
serv.log <src.name> has no shield, but same weapon.
local.parry_percent=<def.bts_weapon_parry_chance>
local.absorb_percent=<def.bts_weapon_absorb_chance>
local.parry_object=<src.find_weapon>
elif (<src.findlayer.1.isweapon>==0) && (<src.findlayer.2.isweapon>==0)
//No weapon + No shield = no parry
serv.log <src.name> has nothing to parry with.
local.parry_percent=0
local.absorb_percent=0
local.parry_object=0
else
//different weapons
serv.log <src.name> has different weapon with you.
local.parry_percent=<eval <def.bts_weapon_parry_chance>/2>
local.absorb_percent=<eval <def.bts_weapon_absorb_chance>/2>
local.parry_object=<src.find_weapon>
endif
if (<argo.isranged>)
//Ranged weapon cant be reflected.
local.parry_percent=0
endif
//***
local.weapon_speed_factor=<eval (<argo.speed>*100)/<def.avarage_speed>>
if (<local.weapon_speed_factor>>100)
serv.log Weapon is Slower than avarage
local.parry_percent = <eval (<local.parry_percent>*100)/<local.weapon_speed_factor>>
else
serv.log Weapon is Faster than avarage
local.absorb_percent = <eval (<local.absorb_percent>*<local.weapon_speed_factor>)/100>
endif
serv.log PARRY PERCENT = <dlocal.parry_percent>
serv.log ABSORB PERCENT = <dlocal.absorb_percent>
//Шанс попадения
local.hit_chance = <eval <eval (((<tactics>/5) + <<tag.hit_skill>>)*(<dex>))*4>/1000>
local.dodge_chance = <eval <eval ((100 + <src.tactics>)*(<src.<tag.hit_skill>>/10))*<src.dex>>/100000>
local.parry_chance = <eval <eval ((<local.parry_percent>+<local.absorb_percent>)*<src.parrying>)*4>/1000>
local.sum=<eval <local.hit_chance>+(<local.dodge_chance>+<local.parry_chance>)>
local.throw=<eval rand(<local.sum>)>
serv.log <name> attack:
serv.log Dodge Chance: <eval (<local.dodge_chance>*100)/<local.sum>>%
serv.log Parry Chance: <eval (<local.parry_chance>*100)/<local.sum>>%
serv.log Hit Chance: <eval (<local.hit_chance>*100)/<local.sum>>%
IF (<LOCAL.DODGE_CHANCE>><LOCAL.THROW>)
// Dodge //
serv.log Dodge
src.skill_gain Tactics,80
skill_gain Tactics,50
skill_gain <tag.hit_skill>,60
src.sound <eval 562+<R2>>
src.sysmessage @0,3,0 Вы увернулись от удара противника.
sysmessage @0,3,0 Промах!
return 1
ELIF (<eval <local.parry_chance> + <local.dodge_chance>>><LOCAL.THROW>)
// Parrying //
serv.log Parry
src.sysmessage @0,3,0 Вы паррировали удар.
sysmessage @0,3,0 Ваш удар был паррирован.
bark 2
src.skill_gain Parrying,100
src.skill_gain Tactics,40
skill_gain <tag.hit_skill>,40
skill_gain Tactics,40
if (<eval rand(<local.parry_percent>+<local.absorb_percent>)>><local.parry_percent>)
//Absorb
IF (<eval RAND(10+(10*(<src.armslore>/1000)))>==1) //Шанс повредить оборонительный обьект = 10 + 10 * (АрмсЛор/100.0).
try uid.<local.parry_object>.damage 1000
ENDIF
else
//Parry
IF (<eval RAND(20+(20*(<src.armslore>/1000)))>==1) //Шанс повредить оборонительный обьект при паррировании = 20 + 20 * (АрмсЛор/100.0).
try uid.<local.parry_object>.damage 1000
ENDIF
endif
IF (<eval RAND(15+((15*<armslore>/1000)))>==1) //Шанс повредить атакующий обьект = 15 + 15 * (АрмсЛор/100.0).
try uid.<ARGO>.damage 1000
ENDIF
return 1
ENDIF
// Hit //
tag.FinalDam = <eval rand(<tag.hit_dam>)>
serv.log Random Dam = <dtag.FinalDam>
tag.FinalDam = <eval (<tag.FinalDam>/2) + (((<tag.FinalDam>/2) * <STR> * <<tag.hit_skill>> * 100)/10000000)>
serv.log Final Dam = <dtag.FinalDam>
// Тест на крит //
local.critical_throw=<EVAL ((RAND(1000)+(<ARMSLORE>/10))*<tag0.perk.critical>)/<src.tag0.perk.intuition>>
IF ((<local.critical_throw>><DEF.CRIT_CHANCE>))
// Крит - не учитываем броню //
serv.log Critical!
src.f_generate_blood <def.crit_blood>
trysrc <src> src.uid.<ARGO>.trigger @Critical
IF (<ARGO.ISRANGED>)
trysrc <src> src.uid.<findid.<ARGO.tag.arrow_type>>.trigger @Critical //Для стрел
ENDIF
obj=<src> //Passing Armor
if (<ARGO>) //We have a weapon
call calc_armor_damage
else
call calc_armor_damage_wrestling
endif
Else
// Крита нет - считаем по броне //
// Куда попали //
tag.hit_layer=<src.findlayer.<src.random_armor_part>>
if ((<tag.hit_layer>==0) || (<uid.<tag.hit_layer>.isarmor>==0)) && (<src.npc>) //Naked NPC (Monster)
tag.hit_layer=<src>
endif
obj=<tag.hit_layer>
if (<ARGO>) //We have a weapon
call calc_armor_damage
else
call calc_armor_damage_wrestling
endif
endif
serv.log Final Dam = <dtag.FinalDam>
if (<local.parry_object>)
src.skill_gain Parrying,40
endif
skill_gain <tag.hit_skill>,100
skill_gain Tactics,100
trysrc <src.uid> src.uid.<ARGO>.trigger @HitEnemy //Триггер подсчета урона для оружия
IF (<ARGO.ISRANGED>)
trysrc <src> src.uid.<findid.<ARGO.tag.arrow_type>>.trigger @HitEnemy //Для стрел
ENDIF
IF (<eval RAND(15+(15*(<armslore>/1000)))>==1) //Повреждаем оружие
try uid.<ARGO>.damage 1000
ENDIF
IF (<eval RAND(15+(15*(<src.armslore>/1000)))>==1) && (<uid.<tag.hit_layer>.ischar>==0) //Повреждаем броню врага
try uid.<tag.hit_layer>.damage 1000
ENDIF
//tag.FinalDam +=<R5>
//tag.FinalDam -=2
src.damage <tag.FinalDam>,2,<UID>
bark 2
tag.hit_started=0
HIT_RESET
return 1
on=@GetHit
IF (<SRC.NPC> && !(<SRC.REGION.FLAGS> & REGION_FLAG_GUARDED) && (<REGION.FLAGS> & REGION_FLAG_GUARDED))
SRC.EFFECT 3, i_fx_glow, 3, 20, 1
return 1
ENDIF
IF (<FLAGS>&STATF_DEAD)
return 1
ENDIF
IF ((<ARGN2>&DAM_FIRE) && (<CAN>&MT_FIRE_IMMUNE))
ARGN1=0
return 0
ENDIF
local.PreviousDam=<src.tag.FinalDam> //Сохраняем урон вызванный для этой функции
src.tag.FinalDam=<ARGN1> //Записываем текущий урон в переменную для последующей обработки
if (<src.tag0.hit_layer>)
try uid.<src.tag.hit_layer>.trigger @OwnerGetHit //Вызываем триггер на арме
endif
if (<src.findlayer.2.type>==t_shield)
try uid.<src.findlayer.2>.trigger @OwnerGetHit //Вызываем триггер на арме
endif
IF (<TAG0.DAMAGERESISTANCE>>0) //ЗАЩИЩАЕМ РЕДАКШНОМ
sysmessage @900,3,0 Вы защитились от <eval <tag0.damageresistance>> едениц урона.
src.tag.FinalDam -=<tag0.damageresistance>
ENDIF
IF (<SRC.TAG.FINALDAM>==-255)
src.tag.FinalDam=0
ELIF (<SRC.TAG.FINALDAM><=0) //ВЫРАВНИВАЕМ УРОН
src.tag.FinalDam=<eval rand(<def.min_damage>)>
ENDIF
ARGN1=<src.tag.FinalDam> //Устанавливаем в урон новые значения
src.tag.FinalDam=<local.PreviousDam> //Восстанавливаем утраченное значение оригинального урона для родительской функции
IF (<UID>!=<SRC.UID>)
IF (<ARGN2>&DAM_POISON)
message @68,3,0 -<eval <ARGN1>>
ELIF (<ARGN2>&DAM_MAGIC)
message @5,3,0 -<eval <ARGN1>>
ELSE
message @72,3,0 -<eval <ARGN1>>
ENDIF
ENDIF
IF ((<ARGN2>&DAM_POISON)==0)
f_check_paralyze
f_check_reactive <ARGN1>
f_generate_blood 1
ELIF (<ARGN1>>15)
ARGN1=<eval 13+<R5>> //Fix for poison
ENDIF
f_check_war_flags
IF (<NPC>==0)
trysrc <uid> src.message @33,3,0 -<eval <ARGN1>>
ENDIF
bark 3
ARGN2=dam_god
IF ((<NPC>) && (<FINDLAYER.2.TYPE>!=T_WEAPON_BOW) && (<FINDLAYER.2.TYPE>!=T_WEAPON_XBOW))
IF (<HITS>>0) && (<ARGN1><<HITS>)
IF (<SRC.DIR><4)
RUN <eval (<SRC.DIR>+4)>
ELSE
RUN <eval (<SRC.DIR>-4)>
ENDIF
ENDIF
ENDIF
return 0
[FUNCTION calc_armor_damage] //inline
//obj - итем по которому мы попали
//argo - оружие которым попали
//uid - чар который аттакует
//src - чар по которому бьют
//tag.FinalDam - урон
// Weapon
// TAG.DAM_SLASH
// TAG.DAM_FENCE
// TAG.DAM_BLUNT
// Armor
// TAG.RES_SLASH
// TAG.RES_FENCE
// TAG.RES_BLUNT
local.armor_class=<eval (((<argo.tag.dam_slash>*<obj.tag.res_slash>)+(<argo.tag.dam_fence>*<obj.tag.res_fence>)+(<argo.tag.dam_blunt>*<obj.tag.res_blunt>))*<strarg <obj.armor>>)/10000>
assert 364,<local.armor_class><200
assert 365,<local.armor_class>>0
tag.FinalDam=<eval ((100-((<local.armor_class>*2)/3))*<tag.FinalDam>)/100>
[FUNCTION calc_armor_damage_wrestling]
local.armor_class=<eval (((<tag.dam_slash>*<obj.tag.res_slash>)+(<tag.dam_fence>*<obj.tag.res_fence>)+(<tag.dam_blunt>*<obj.tag.res_blunt>))*<strarg <obj.armor>>)/10000>
assert 366,<local.armor_class><200
assert 367,<local.armor_class>>0
tag.FinalDam=<eval ((100-((<local.armor_class>*2)/3))*<tag.FinalDam>)/100>
[FUNCTION damtype_parent]
if (<ischar>)
TAG.DAM_SLASH=<serv.chardef.<body>.tag.dam_slash>
TAG.DAM_FENCE=<serv.chardef.<body>.tag.dam_fence>
TAG.DAM_BLUNT=<serv.chardef.<body>.tag.dam_blunt>
else
TAG.DAM_SLASH=<serv.itemdef.<id>.tag.dam_slash>
TAG.DAM_FENCE=<serv.itemdef.<id>.tag.dam_fence>
TAG.DAM_BLUNT=<serv.itemdef.<id>.tag.dam_blunt>
endif
[FUNCTION armortype_parent]
if (<ischar>)
TAG.RES_SLASH=<serv.chardef.<body>.tag.RES_slash>
TAG.RES_FENCE=<serv.chardef.<body>.tag.RES_fence>
TAG.RES_BLUNT=<serv.chardef.<body>.tag.RES_blunt>
else
TAG.RES_SLASH=<serv.itemdef.<id>.tag.RES_slash>
TAG.RES_FENCE=<serv.itemdef.<id>.tag.RES_fence>
TAG.RES_BLUNT=<serv.itemdef.<id>.tag.RES_blunt>
endif
[FUNCTION shieldtype_parent]
TAG.CHANCE_PARRY=<serv.itemdef.<id>.tag.CHANCE_PARRY>
TAG.CHANCE_ABSORB=<serv.itemdef.<id>.tag.CHANCE_ABSORB>
[FUNCTION HIT_RESET]
SERV.NEWITEM=i_hit_reset
NEW.P=<P>
NEW.LINK=<UID>
NEW.TIMERD=2
[ITEMDEF i_hit_reset]
ID=i_memory
TYPE=t_script
ON=@TIMER
if (<LINK.TAG.HIT_STARTED>==0)
TRY LINK.TIMER=0
endif
REMOVE
RETURN 1
[FUNCTION HIT_DISTANCE_RESET]
consume 1 i_hit_distance_reset
serv.newitem i_hit_distance_reset
new.cont <uid>
new.link=<argn1>
new.timer=<argn2>/20
if (<new.timer><1)
new.remove
endif
[ITEMDEF i_hit_distance_reset]
ID=i_memory
TYPE=t_eq_script
on=@Timer
if (<link.uid>==0)
remove
return 1
endif
if (<cont.distance <link>>>2)
cont.action -1
endif
remove
return 1
[FUNCTION random_armor_part]
DORAND 15
local.hit_layer=layer_chest
local.hit_layer=layer_chest
local.hit_layer=layer_chest
local.hit_layer=layer_chest
local.hit_layer=layer_chest
local.hit_layer=layer_legs
local.hit_layer=layer_legs
local.hit_layer=layer_legs
local.hit_layer=layer_arms
local.hit_layer=layer_arms
local.hit_layer=layer_arms
local.hit_layer=layer_helm
local.hit_layer=layer_helm
local.hit_layer=layer_gloves
local.hit_layer=layer_collar
ENDDO
serv.log LAYER=<local.hit_layer>
if (<local.hit_layer>==layer_legs) && (<findlayer.layer_legs.isarmor>==0)
local.hit_layer=layer_pants
endif
if (<local.hit_layer>==layer_chest) && (<findlayer.layer_chest.isarmor>==0)
local.hit_layer=layer_shirt
endif
return <local.hit_layer>
[FUNCTION find_weapon]
if (<findlayer.1.isweapon>)
return <findlayer.1>
elif (<findlayer.2.isweapon>)
return <findlayer.2>
else
return 0
endif
[FUNCTION f_check_war_flags]
FORCHARMEMORYTYPE MEMORY_SAWCRIME
IF (<LINK>==<SRC.UID> )
TIMER=120
ENDIF
ENDFOR
FORCHARMEMORYTYPE MEMORY_HARMEDBY
IF (<LINK>==<SRC.UID> )
TIMER=120
ENDIF
ENDFOR
[FUNCTION f_check_paralyze]
IF (<FLAGS>&STATF_FREEZE)
flags &= ~statf_freeze
findid.i_rune_paralyze.remove
ENDIF
[FUNCTION f_check_reactive]
IF (<FLAGS>& STATF_REACTIVE)
src.effect 3, i_fx_curse, 3, 10
IF (<FINDLAYER(33).UID>)
local.react = <findlayer(33).morey>
ELSE
local.react = <MAGICRESISTANCE>
ENDIF
local.react = <eval (((<ARGS> * <local.react>)/5000)+1)>
src.hits = <eval (<src.hits> - <local.react>)>
src.update
ENDIF
[FUNCTION f_generate_blood]
IF (<BLOODCOLOR>==0FFFF)
return 0
ENDIF
FOR <ARGS>
IF (RAND(2)==1)
SERV.NEWITEM=i_blood
NEW.DispID={0122a 1 0122b 1 0122c 1 0122d 1 0122e 1 0122f 1}
NEW.ATTR=attr_decay|attr_move_never
new.color=<bloodcolor>
NEW.P=<P>
NEW.P=<eval (<P.X>+<R3>-1)> <eval (<P.Y>+<R3>-1)> <P.Z>
NEW.TIMER={100 300}
if (<NEW.f_test_blood_under>)
new.remove
endif
ENDIF
ENDFOR
[FUNCTION f_test_blood_under]
local.timer=<timer>
local.this=<uid>
foritems 0
if (<baseid>==i_blood) && (<uid>!=<local.this>)
timer +=<local.timer>
if (<timer>>1000)
timer=1000
endif
return 1
endif
endfor
return 0
[function f_damage_weapon]
try uid.<args>.damage=1000,2,<uid>
[function f_damage_armor]
IF ((<FINDLAYER.2.TYPE>==T_SHIELD) && (RAND(13)==0))
findlayer.2.damage=1000,2,<uid>
ELSE
DORAND 12
findlayer(layer_tunic).damage=1000,2,<src.uid>
findlayer(layer_robe).damage=1000,2,<src.uid>
findlayer(layer_skirt).damage=1000,2,<src.uid>
findlayer(layer_cape).damage=1000,2,<src.uid>
findlayer(layer_tunic).damage=1000,2,<src.uid>
findlayer(layer_chest).damage=1000,2,<src.uid>
findlayer(layer_arms).damage=1000,2,<src.uid>
findlayer(layer_helm).damage=1000,2,<src.uid>
findlayer(layer_pants).damage=1000,2,<src.uid>
findlayer(layer_legs).damage=1000,2,<src.uid>
findlayer(layer_collar).damage=1000,2,<src.uid>
findlayer(layer_gloves).damage=1000,2,<src.uid>
ENDDO
ENDIF
[EOF]