PenUltima Online Forum Index Official Core: 096.7
Official Core: 097 2008-02-26
Donate towards the POL web hosting bill!
 POL Home   FAQ   Search    Memberlist   Usergroups    Register    Profile   Log in to check your private messages   Log in
Mobile.swing()

 
Post new topic   Reply to topic    PenUltima Online Forum Index -> Feature Suggestions
Display posts from previous:   

Author Message
Bracco



Joined: 28 Dec 2006
Posts: 80

PostPosted: Sun Jan 14, 2007 12:02 pm    Post subject: Mobile.swing() Reply with quote

title is not so clear Razz but i mean a method for mobiles that causes an attack with the weapon (not the animation only)(without waiting the delay and/or movement check for projectables), just like when you are in warmode and swing with your weapon...

useful to implement things such as the aos combat abilities (double strike, moving shot etc)


Last edited by Bracco on Sun Jan 14, 2007 12:30 pm; edited 1 time in total

Author Message
SMJ



Joined: 10 May 2006
Posts: 113

PostPosted: Sun Jan 14, 2007 12:25 pm    Post subject: Reply with quote

Code:
use uo;

function PlayAttackAnimation(byref a_info)
   var attack_anim := ANIM_FIDGET_1; // Default attack anim for NPCs.
   if ( (a_info.cfginfo).Anim )
      // Normal weapons
      var anim_list := GetConfigStringArray(a_info.cfginfo, "Anim");
      attack_anim := anim_list[RandomInt(anim_list.Size())+1];
   elseif ( (a_info.cfginfo).AttackAnimation )
      // NPC intrinsic weapons
      var anim_list := GetConfigStringArray(a_info.cfginfo, "AttackAnimation");
      attack_anim := anim_list[RandomInt(anim_list.Size())+1];
   endif

   PerformAction(a_info.mobile, CInt(attack_anim));

   return attack_anim;
endfunction


Copy-pasted from 096 combatHook.src

Author Message
Bracco



Joined: 28 Dec 2006
Posts: 80

PostPosted: Sun Jan 14, 2007 12:29 pm    Post subject: Reply with quote

SMJ wrote:
Code:
use uo;

function PlayAttackAnimation(byref a_info)
   var attack_anim := ANIM_FIDGET_1; // Default attack anim for NPCs.
   if ( (a_info.cfginfo).Anim )
      // Normal weapons
      var anim_list := GetConfigStringArray(a_info.cfginfo, "Anim");
      attack_anim := anim_list[RandomInt(anim_list.Size())+1];
   elseif ( (a_info.cfginfo).AttackAnimation )
      // NPC intrinsic weapons
      var anim_list := GetConfigStringArray(a_info.cfginfo, "AttackAnimation");
      attack_anim := anim_list[RandomInt(anim_list.Size())+1];
   endif

   PerformAction(a_info.mobile, CInt(attack_anim));

   return attack_anim;
endfunction


Copy-pasted from 096 combatHook.src


hm? i mean a REAL swing, not just the animation...

Author Message
SMJ



Joined: 10 May 2006
Posts: 113

PostPosted: Sun Jan 14, 2007 12:35 pm    Post subject: Reply with quote

Then add the damage, too? I'm sorry, but this already exists in the form of:

Code:
Attack( byref attacker, byref defender );


And the suggestion would limit, rather than expand, POL's combat aesthetics. Every weapon has 9 attack animations, but the coders decide which ones to utilize; by adding them to a custom exported Attack(byref attacker, byref defender) function.

Author Message
Bracco



Joined: 28 Dec 2006
Posts: 80

PostPosted: Sun Jan 14, 2007 12:47 pm    Post subject: Reply with quote

SMJ wrote:
Then add the damage, too? I'm sorry, but this already exists in the form of:

Code:
Attack( byref attacker, byref defender );


And the suggestion would limit, rather than expand, POL's combat aesthetics. Every weapon has 9 attack animations, but the coders decide which ones to utilize; by adding them to a custom exported Attack(byref attacker, byref defender) function.


i dont get it oh dear where's that attack function from? from a script?

i need to cause a physical attack, just as when i am hitting someone with my executioner's axe... it can't be done with attackhook/hitscript, i need to be able to actually cause the attack to happen, not wait till the normal one happens

Author Message
SMJ



Joined: 10 May 2006
Posts: 113

PostPosted: Sun Jan 14, 2007 12:58 pm    Post subject: Reply with quote

That's called "externalizing" and can be very easily done with an include function. All it really means is that you take out all of the contents of a program, stick it in a function, then make a call to it in the function, so that several different scripts can perform identical purposes without copy-pasting too much content.

Code:

program DoStuff(who)
    return DoStuffFunc(who);
endprogram

Code:

function DoStuffFunc(who)
    // Do all the program's functions
endfunction

Author Message
Bracco



Joined: 28 Dec 2006
Posts: 80

PostPosted: Sun Jan 14, 2007 1:08 pm    Post subject: Reply with quote

SMJ wrote:
That's called "externalizing" and can be very easily done with an include function. All it really means is that you take out all of the contents of a program, stick it in a function, then make a call to it in the function, so that several different scripts can perform identical purposes without copy-pasting too much content.

Code:

program DoStuff(who)
    return DoStuffFunc(who);
endprogram

Code:

function DoStuffFunc(who)
    // Do all the program's functions
endfunction


hm... i think you totally misunderstood what i'm saying.

i DON'T want to hook the attack, i want to MAKE IT HAPPEN.
also, i know what hooks, exported functions and such things are.

let me explain in a more ground-to-ground way:

i want to implement, for example, AOS combat ability "Double Strike"
what it does is, basically, to attack 2 times in a row, so when your attack lands another one is instantly fired.

how do you do this nowadays? you can't, unless you do it some tricky way, making a fake attack in an hitscript, but maybe, as you say, you have some attackhook/hitscript you want to run before the new attack lands (if it lands)

not to mention that the movement-check for projectable weapons is done by core, so you won't have anything to hook to implement "Moving Shot" (ofc you can make a "fake attack", but it will result in an heavy script to make it work just as the core does)

Author Message
SMJ



Joined: 10 May 2006
Posts: 113

PostPosted: Sun Jan 14, 2007 1:25 pm    Post subject: Reply with quote

I know exactly what you're saying. You want it to fire twice? Externalize it to a function, and fire it twice. You want it to wait until you would swing normally? Make the command put a cprop on the attacker, and then loop it in the syshook; that way it'll skip the attack delay entirely. I haven't tried using projectiles in a syshook myself, but I don't see why "moving shot" couldn't be done. I don't know exactly how AOS "Moving Shot" works, but if it just means that you use it to shoot while moving; just link a script to it. And if you're worried about a syshook stalling the server, just make the packethook immediately Start_Script another file; and you've solved the problem.

As far as a "heavy script", I don't see where you got that conclusion. 096 AND 097 have a syshook, WOD used a syshook, SxC uses a syshook, I use a syshook, and I have never heard of anyone complaining about ANY of them being slow or heavy.

There is no limit to what you can and cannot do; just a limit to creativity, and what you're willing to try.

Author Message
Bracco



Joined: 28 Dec 2006
Posts: 80

PostPosted: Sun Jan 14, 2007 1:39 pm    Post subject: Reply with quote

SMJ wrote:
I don't know exactly how AOS "Moving Shot" works, but if it just means that you use it to shoot while moving; just link a script to it.


meh, lets suppose that i use a script to make a "fake" attack while moving.

i put a start_script in my packethook that fires the "fake attack" script

so i must do something like this
Code:

if( attackhook )
  call hook
  if hook returned 1, exit
endif

if( weapon is projectile )
  try to comsume projectile
  if none, exit
exit

if( weapon is projected )
  play sound and animations
else
  play attack anim
endif

if( combat advancement hook exists )
  call it
endif

hit_chance = (weapon_attribute + 50.0) / (2.0 * opponent_weapon_attribute + 50.0)

if( random_float(1.0) < hitchance )
  play hit sounds and anims
  damage weapon (1 in 100 chance to lose 1 hp)
 
  damage = random_weapon_die_damage
  damage_multiplier = tactics + 50
  damage_multiplier += strength * 0.2
  damage_multiplier *= 0.01
  damage *= damage_multiplier
 
  if( opponent has shield )
    call parry advancement hook
   
    parry_chance = opponent_parry_skill / 200.0
    if( random_float(1.0) < parry_chance )
      display parry success
      damage -= opponent_shield_ar
    endif
  endif
 
  if( weapon has no hit script )
    choose armor piece hit based on zone coverage percentage
    blocked = armor piece ar + character ar_mod
    absorbed = blocked / 2
    blocked -= absorbed
    absorbed += random_int(blocked+1)
    damage -= absorbed
    if( damage >= 2.0 )
       damage *= 0.5
    endif
    1 in 100 chance for armor piece to lose 1 hp
    play hit animation
    applydamage(damage)
  else
    choose armor piece hit based on zone coverage percentage
    calc base & raw damage (exactly like above if no hit script)
    run hit script
    (Core doesn't damage armor if hitscript, do it in the script)
  endif
else
  play weapon miss sound
endif


that's the core combat pseudocode...
sooo its good to make such a thing in a script that probably will run continuosly during pvp battles?
no its not. moreover, there's really no reason to just make a script clone of an internal core function.

and tbh i dont like filling the scriptbase with intricated, tricky things just to fake out something that it's already been done internally

Author Message
SMJ



Joined: 10 May 2006
Posts: 113

PostPosted: Sun Jan 14, 2007 1:45 pm    Post subject: Reply with quote

Guess what?
Code:
/* $Id: combatHook.src 788 2006-09-05 01:25:54Z AustinHeilman $
 *
 * NOTES:
 *   Return 0 if you want the core to handle the
 *   combat cycle. Return 1 to say that the cycle is over.
 */

use uo;
use os;
use polsys;
use cfgfile;

include ":attributes:attributes";
include ":brainai:npcUtil";
include ":armor:armorZones";
include ":combat:settings";
include ":damage:damage";
include ":itemutils:itemdesc";
include "include/client";
include "include/facings";

/*
 * Global variables
 * With the way hooks work, these are only set only ONCE
 * and stay the same in every instance the hook gets run.
 */
var g_item_cfg := ReadConfigFile(":*:itemdesc");
var g_settings_cfg := CS_GetSettingsCfgFile();

program Install()
   print("INSTALLING: Combat hook... ");
   return 1;
endprogram

exported function Attack(attacker, defender)
   if ( !g_settings_cfg["Settings"].EnableHook )
      return 0;
   elseif ( !CanAttack(attacker, defender) )
      return 1;
   endif

   var a_info, d_info;
   SetupInfo(attacker, defender, a_info, d_info);

   if ( !DistanceChecks(a_info, d_info) )
      return 1;
   elseif ( !AmmoChecks(a_info, d_info) )
      return 1;
   endif

   FacingChecks(attacker, defender);
   PlayAttackAnimation(a_info);

   var hit_chance := CalcHitDifficulty(a_info, d_info);
   if ( RandomFloat(1.0) < hit_chance )
      var attribute := GetConfigString(a_info.cfginfo, a_info.prefix+"Attribute");
      var gain_flag := GetCombatGainFlags(attacker, defender);
      SkillCheck(attacker, attribute, -1, 0, gain_flag);

      PlayHitSound(a_info, d_info);

      var base_damage := CalcBaseDamage(a_info);
      var raw_damage := base_damage;
      ParryChecks(attacker, defender, raw_damage);

      var armor_hit := GetArmorHit(d_info);
      ArmorChecks(d_info, armor_hit, raw_damage);

      RunWeaponHitScripts(a_info, d_info, armor_hit, base_damage, raw_damage);
      RunArmorHitScripts(a_info, d_info, armor_hit, base_damage, raw_damage);

      ApplyRawDamageEX(d_info.mobile, raw_damage, DMG_FORCED, a_info.mobile);
   else
      PlayMissSound(a_info);
   endif

   return 1;
endfunction

function GetCombatGainFlags(attacker, defender)
   if ( defender.npctemplate )
      return ADV_ALL;
   elseif ( attacker.npctemplate )
      return ADV_ALL;
   elseif ( g_settings_cfg["Settings"].PvPGains )
      return ADV_ALL;
   else
      return ADV_DISABLE;
   endif
endfunction

function CanAttack(attacker, defender)
   // These first two checks are handled by the core.
   //if ( attacker == defender )
   //   return 0;
   //elseif ( !CheckLineOfSight(attacker, defender) )
   //   return 0;
   //
   if ( !attacker.warmode && !g_settings_cfg["Settings"].AutoDefend )
      return 0;
   endif

   return 1;
endfunction

function FacingChecks(attacker, defender)
   if ( g_settings_cfg["Settings"].ForceFacing )
      if ( !IsFacing(attacker, defender.x, defender.y) )
         TurnObjectToward(attacker, defender.x, defender.y);
      endif

      if ( !IsFacing(defender, attacker.x, attacker.y) )
         TurnObjectToward(defender, attacker.x, attacker.y);
      endif
   endif

   return 1;
endfunction

function DistanceChecks(byref a_info, byref d_info)
   // Core handles distance checks before starting the hook.
   return 1;
   /*
   var cur_range := Distance(a_info.mobile, d_info.mobile);
   var max_range := GetConfigInt(a_info.cfginfo, a_info.prefix+"MaxRange");
   if ( max_range == error )
      max_range := 1;
   endif

   if ( cur_range > max_range )
      CombatMsg(a_info.mobile, "Opponent is too far away. ["+max_range+"]", "Dist");
      return 0;
   elseif ( cur_range < CInt(GetConfigInt(a_info.cfginfo, a_info.prefix+"MinRange")) )
      CombatMsg(a_info.mobile, "Opponent is too close.", "Dist");
      return 0;
   else
      return 1;
   endif
   */
endfunction

function AmmoChecks(byref a_info, byref d_info)
   var ammo_type := CInt((a_info.cfginfo).ProjectileType);
   if ( !ammo_type )
      return 1;
   endif

   if ( ConsumeSubstance((a_info.mobile).backpack, ammo_type, 1) )
      PlaySoundEffect(a_info.mobile, CInt((a_info.cfginfo).ProjectileSound));
      PlayMovingEffect(a_info.mobile, d_info.mobile, (a_info.cfginfo).ProjectileAnim, 10, 0);
      return 1;
   else
      CombatMsg(a_info.mobile, "You do not have any "+GetObjTypeDesc(ammo_type, 1)+"!", "Ammo");
      return 0;
   endif
endfunction

function PlayAttackAnimation(byref a_info)
   var attack_anim := ANIM_FIDGET_1; // Default attack anim for NPCs.
   if ( (a_info.cfginfo).Anim )
      // Normal weapons
      var anim_list := GetConfigStringArray(a_info.cfginfo, "Anim");
      attack_anim := anim_list[RandomInt(anim_list.Size())+1];
   elseif ( (a_info.cfginfo).AttackAnimation )
      // NPC intrinsic weapons
      var anim_list := GetConfigStringArray(a_info.cfginfo, "AttackAnimation");
      attack_anim := anim_list[RandomInt(anim_list.Size())+1];
   endif

   PerformAction(a_info.mobile, CInt(attack_anim));

   return attack_anim;
endfunction

function CalcHitDifficulty(byref a_info, byref d_info)
   //hit_chance = (weapon_attribute + 50.0) / (2.0 * opponent_weapon_attribute + 50.0)
   var a_skill := AP_GetSkill(a_info.mobile, GetConfigString(a_info.cfginfo, a_info.prefix+"Attribute"));
   var d_skill := AP_GetSkill(d_info.mobile, GetConfigString(d_info.cfginfo, d_info.prefix+"Attribute"));

   return ((a_skill + 50.0) / (2.0 * d_skill + 50));
endfunction

function PlayHitSound(byref a_info, byref d_info)
   var hit_sound := GetConfigStringArray(a_info.cfginfo, a_info.prefix+"HitSound");
   hit_sound := hit_sound[RandomInt(hit_sound.Size())+1];
   PlaySoundEffect(a_info.mobile, CInt(hit_sound));

   var damaged_sound;
   if ( (d_info.mobile).npctemplate )
      damaged_sound := GetConfigStringArray(d_info.cfginfo, "DamagedSound");
   else
      case ( (d_info.mobile).gender )
         0:// Male
            damaged_sound := array{341, 342, 343, 345, 346};
            break;
         1://Female
            damaged_sound := array{332, 333, 334, 335, 336};
            break;
      endcase
   endif
   damaged_sound := damaged_sound[RandomInt(damaged_sound.Size())+1];

   PlaySoundEffect(d_info.mobile, CInt(damaged_sound));

   return 1;
endfunction

function PlayMissSound(byref a_info)
   var miss_sound := GetConfigStringArray(a_info.cfginfo, a_info.prefix+"MissSound");
   miss_sound := miss_sound[RandomInt(miss_sound.Size())+1];
   PlaySoundEffect(a_info.mobile, CInt(miss_sound));

   return 1;
endfunction

function CalcBaseDamage(byref a_info)
   var base_dmg := GetConfigString(a_info.cfginfo, a_info.prefix+"Damage");
   base_dmg := RandomDiceRoll(base_dmg);

   var dmg_mult := CDbl(AP_GetSkill(a_info.mobile, TACTICS))+50.0;
   dmg_mult += (CDbl(AP_GetStat(a_info.mobile, STRENGTH)) * 0.2);
   dmg_mult := CDbl(dmg_mult) * 0.01;
   base_dmg *= dmg_mult;

   return CInt(base_dmg);
endfunction

function ParryChecks(byref a_info, byref d_info, byref raw_damage)
   var shield := (d_info.mobile).shield;
   if ( !shield )
      return 0;
   endif

   var parry_elem := g_settings_cfg["Parry"];
   var divisor := CDbl(parry_elem.ParryDivisor);
   var roll := CDbl(parry_elem.ParryRoll);
   var parry_chance := CDbl(AP_GetSkill(a_info.mobile, PARRY)) / divisor;

   if ( RandomFloat(roll) < parry_chance )
      PerformAction(d_info.mobile, ANIM_TWIST_DODGE);
      SendSysMessage(d_info.mobile, "You deflect some damage using your shield.");
      raw_damage -= shield.ar;

      var armor_elem := g_settings_cfg["Armor"];
      if ( RandomInt(100)+1 <= armor_elem.WearChance )
         SendSysMessage(d_info.mobile, shield.desc+" takes some damage.");
         shield.hp -= 1;

         if ( shield.hp <= 1 )
            MoveObjectToLocation(shield, 1, 1, 1, shield.realm, MOVEOBJECT_FORCELOCATION);
            SendSysMessage(d_info.mobile, shield.desc+" has been destroyed.");
            DestroyItem(shield);
         endif
      endif
   endif

   return 1;
endfunction

function GetArmorHit(byref d_info)
   var hit_zone := CS_GetRandomArmorZone();
   var armor_hit := CS_GetEquipmentInArmorZone(d_info.mobile, hit_zone);

   if ( armor_hit.Size() < 1 )
      return 0;
   endif

   var best_armor := 0;
   foreach item in ( armor_hit )
      if ( item.ar > best_armor.ar )
         best_armor := item;
      endif
      SleepMS(2);
   endforeach

   return best_armor;
endfunction

function ArmorChecks(byref d_info, armor_hit, byref raw_damage)
   var blocked := CInt(armor_hit.ar) + (d_info.mobile).ar_mod;
   var absorbed := blocked / 2;
   blocked := blocked - absorbed;
   absorbed := absorbed + RandomInt(blocked+1)+1;
   raw_damage := raw_damage - absorbed;

   if ( raw_damage >= 2.0 )
      raw_damage := raw_damage * 0.5;
   endif
   raw_damage := CInt(raw_damage);

   if ( !armor_hit.IsA(POLCLASS_ARMOR) )
      return 1;
   endif

   var armor_elem := g_settings_cfg["Armor"];
   if ( RandomInt(100)+1 <= armor_elem.WearChance )
      SendSysMessage(d_info.mobile, armor_hit.desc+" takes some damage.");
      armor_hit.hp -= 1;

      if ( armor_hit.hp <= 1 )
         MoveObjectToLocation(armor_hit, 1, 1, 1, armor_hit.realm, MOVEOBJECT_FORCELOCATION);
         SendSysMessage(d_info.mobile, armor_hit.desc+" has been destroyed.");
         DestroyItem(armor_hit);
      endif
   endif

   return 1;
endfunction

function RunWeaponHitScripts(byref a_info, byref d_info, armor_hit, base_damage, raw_damage)
   var weapon_scripts := array{};
   if ( ((a_info.mobile).weapon).intrinsic )
      weapon_scripts := GetObjProperty(a_info.mobile, "HitScripts");
   elseif ( ((a_info.mobile).weapon).IsA(POLCLASS_WEAPON) )
      weapon_scripts := GetObjProperty((a_info.mobile).weapon, "HitScripts");
   endif

   var params := array{a_info.mobile, d_info.mobile, (a_info.mobile).weapon, armor_hit, base_damage, raw_damage};
   foreach hitscript in ( weapon_scripts )
      var script := Start_Script(hitscript, params);
      if ( !script || script.errortext )
         SendSysMessage(a_info.mobile, "*Attacker* Weapon script error starting ["+hitscript+"] :"+script.errortext);
         SendSysMessage(d_info.mobile, "*Attacker* Weapon script error starting ["+hitscript+"] :"+script.errortext);
      endif
      SleepMS(2);
   endforeach

   return 1;
endfunction

function RunArmorHitScripts(byref a_info, byref d_info, armor_hit, base_damage, raw_damage)
   var body_scripts := GetObjProperty(d_info.mobile, "ArmorHitScripts");
   var armor_scripts := GetObjProperty(armor_hit, "ArmorHitScripts");
   if ( !body_scripts )
      body_scripts := array{};
   endif
   if ( !armor_scripts )
      armor_scripts := array{};
   endif

   armor_scripts := armor_scripts + body_scripts;

   var params := array{a_info.mobile, d_info.mobile, (a_info.mobile).weapon, armor_hit, base_damage, raw_damage};
   foreach hitscript in ( armor_scripts )
      var script := Start_Script(hitscript, params);
      if ( !script || script.errortext )
         SendSysMessage(a_info.mobile, "*Defender* Armor script error starting ["+hitscript+"] :"+script.errortext);
         SendSysMessage(d_info.mobile, "*Defender* Armor script error starting ["+hitscript+"] :"+script.errortext);
      endif
      SleepMS(2);
   endforeach

   return 1;
endfunction

function SetupInfo(attacker, defender, byref a_info, byref d_info)
   a_info := struct;
   a_info.+mobile := attacker;
   if ( attacker.IsA(POLCLASS_NPC) && (attacker.weapon).intrinsic )
      a_info.+prefix := "Attack";
      a_info.+cfginfo := NPC_GetNPCConfig(attacker.npctemplate);
   else
      a_info.+prefix := "";
      a_info.+cfginfo := g_item_cfg[(attacker.weapon).objtype];
   endif

   d_info := struct;
   d_info.+mobile := defender;
   if ( defender.IsA(POLCLASS_NPC) && (defender.weapon).intrinsic )
      d_info.+prefix := "Attack";
      d_info.+cfginfo := NPC_GetNPCConfig(defender.npctemplate);
   else
      d_info.+prefix := "";
      d_info.+cfginfo := g_item_cfg[(defender.weapon).objtype];
   endif

   return 1;
endfunction

function CombatMsg(mobile, text, type:="")
   // This is done just to prevent message spam on fast weapons.
   if ( CInt(GetObjProperty(mobile, "#CH-Msg"+type)) < ReadMillisecondClock() )
      SendSysMessage(mobile, text);
      SetObjProperty(mobile, "#CH-Msg"+type, ReadMillisecondClock()+800);
   endif

   return 1;
endfunction


The distro already does it. And nobody's complained. And it really doesn't get that much overhead.

Either apply my advice, or ignore it. I'm never going to use AOS systems; I wasn't particularly impressed with them; but I have seen entire shards pull this kind of thing off, and the distro actually uses it by default. If you get complaints about this being slow, then it's your computer, not POL.


Last edited by SMJ on Sun Jan 14, 2007 1:52 pm; edited 1 time in total

Author Message
Bracco



Joined: 28 Dec 2006
Posts: 80

PostPosted: Sun Jan 14, 2007 1:50 pm    Post subject: Reply with quote

fine, so you're telling there's no reason to have it core side no?

well, i disagree. have you ever seen how such scripts can suck up resources when there are a coulpe hundreds ppl online fighting continuously?

i have, and i didn't like the result

edit: advice what? you just came here and sentenced it itsn't necessary. also you say that its good to use crappy methods, just pump up the hardware (oh, just to point it out, hooking isnt a crappy method, faking an entire existing system is)

btw, enough with discussion. let devs decide if this is worth implementing or not

Author Message
Austin
POL Developer


Joined: 30 Jan 2006
Posts: 354
Location: San Diego, California

PostPosted: Tue Jan 30, 2007 4:18 pm    Post subject: Reply with quote

The nice thing about hooked (exported) scripts is that the core caches.. sort of.. remembers the code. This is why they cant be unloaded and reloaded, too.

It just goes through and refreshes the data it is instructed to.. very optimized part of the execution engine. Only one instance of a hook can run at a time but they run so quickly and in their own threads, that they it isn't too big a deal.

Author Message
MuadDib
POL Developer


Joined: 13 Feb 2006
Posts: 830
Location: Indiana, USA

PostPosted: Tue Jan 30, 2007 10:40 pm    Post subject: Reply with quote

Actually for aos combat systems like the double strike, etc, it IS doable without hooking the core combat. To the best of my knowledge about the only thing not doable is the Lightning Strike of Bushido because it enhances your ability to hit the opponent (totally core controlled). The others are modifiers to the successful attack. Others are speed mods, which .delay can be used for this now with core combat without hooking. I have not messed with combat hooks, so don't know personally if you can set the hit percentage chance in the script or not. If so, then even lightning strike is done.

From my personal pvp/pvm on OSI, with all the basic skills, Spellweaving, Bushido, Necro, Chivalry, etc (all cept ninjitsu), including the combat book mods, it's all doable in the hitscripts and so forth without hardly any overhead required at all. Only if you must hook core combat might that make more overhead than desired I would think.

Post new topic   Reply to topic    PenUltima Online Forum Index -> Feature Suggestions All times are GMT - 4 Hours
Page 1 of 1

 




Powered by phpBB © 2001, 2005 phpBB Group :: Theme & Graphics by GHS & Scott E. Royalty