Spell Revamp Campain.

Discussions on various DOL development features

Moderator: Support Team

Spell Revamp Campain.

Postby Leodagan » Tue Nov 04, 2014 6:35 pm

Ok Now that I'm finish with class career let's get on the next step :

Get Spell handlers clean !

This is way easier to say than to do :)

But actually I had quite some work done, mostly tested, not up to the quality I wanted it, but now with Career implementation I can have a new view on this matter !

So Here what I'm expecting to do around spells :
  • Sort all existing spell handlers out, a lot of them are having duplicate effects or similar effects, a lot of them could inherit other spell handler to obtain the expected behavior
  • Remove "Hardcoded" Spell Handler, Sorry for the guys who did all this "Astral Work" or this "Master Level" implementation, or even some specific class like Heretic, Bainshee, Necromancer, Bonedancer, and Warlock spell handler... most of them could inherit "base" existing spell handler and obtain the desired effect will only small override, this is a whole mess actually, some Subclass are just meant to hardcode some specific values, some spell handler are totally copy/paste from other file to mimic the spell effect with small differences...
  • Update most Spell Handler to extend "DOL Event Handlers", actually a lot of spell use hardcoded checks in Living or Player class to match the desired effect if the spell handler can be found on the game object... I admit there are some trouble with DOL event Handler that are not "predictive" you don't know if an other event will garbage the data your listening to or do anything based on the result of the data that your handler will change !
    There is still a wide range of use for these handler, listening to spell casting to change target with specific ML spells, handle chambers as "spell effects" instead of having it all hardcoded in player code...
    Bladeturn are the best example of the spells that could use this behavior, and the best example to show the need of having precise event that could occur before or after any action taken (bladeturn could mess with health buffer if no order is enforced !!)
  • Improve the actual base SpellHandler Implementation to be more generic and handle nicely even specific spell handler (Focus Handling is a mess actually and can't handle an AOE focus effect, Song Handling is not great it's targeted to beneficial group buff effect and is a mess when used for Flute Mezz which must be implemented as a spell most of the time !)
    Most of my code improvements rely on this strong review of the Spell Handler object, more than 60% of the code changed, this allow for pretty easier implementation of most specific spells like Heretics, or Bainshee, or Vampiir, and even allow for easier implementation of recent poisons.
  • Unfortunately these updates will come with strong revision of "fighting rules" from GameLiving and GamePlayer code, this also come with a huge update of Summoning Code and GamePet subclasses, which will have some effect on "StandardBrain" to work correctly, the Spell data table will need a lot of updates to take care of all effect change, even if some "synonyms" can be kept for some time, Summoning will need some NPCTemplate update, behavior of pets are supposed to be mostly configured through this table to reduce the need of custom summoning spell handlers...
    So to take advantage of these updates a lot of work must be done by shards admins, I expect to use the new "SpellProperties" Table to add spell some custom values instead of using weird fields like "LifeDrainReturn, ResurrectHealth, ResurrectMana etc..." (default should be handled to prevent any errors)

I'm building a new branch for the time I will need to Merge and finish this work :

https://svn.code.sf.net/p/dolserver/cod ... lerRevamp/

I'm starting by getting rid of "class specific" Spell Handlers, sorting Spell by their Type (Damage, CC, Debuff, Buff, Summon etc...) and changing folder tree to match this.

Then I will try to match the file that need changes from the point I stopped, but I can't Merge all this blindly... Even if I've done a lot of work these last months, there are new ideas that spotted since, so I will rather try to work this carefully, starting by revamping the Base "Spell Handler" implementation so every spell handler that subclass it can change the behavior in the way they need.

To make things clear about the purpose of this update :

Latest Tooltip update from DAOC Live showed that most rules of the game are tied to spells !!

Abilities Effects, Realm Abilities Effect, Spells Effects, Styles Effects, Terrains Effects, ML effects, ANY Skills effect is a SPELL !

In fact this make pretty much sense, spells are made able to change so much properties of the game, they are meant to BEND rules around players actions !

We don't need any other "Behavior" handlers than spell handlers, even for weird effects... Actually the "Spell Casting Ability" (for some RA's) is pretty much implemented like this, it's just a special container that will run it's own "CheckCast()" method before using Spell Methods that shouldn't be used like this for casting sequences !! Then it will mostly cap damage calc to work even if no spell lines or Specializations are attached...

New Career System changed some of this, now we can always connect any "used skill" to a given Spec and may find some data about attached spell line or default levels for "skills"...

So when we need to implement more and more special effects, we shouldn't try to customize GameLiving, GameNPC or GamePlayer Classes except if we need more fine-grained event handler, all the code should be in Spell Handlers using massively these events !

I want to get rid of Bersker specific defense malus code, I want to get rid of Body guard Specific checks, I want to get rid of Intercept, Guard, BladeTurn, Advanced Evade, and EVEN Parry and Block code !! Without even talking of the Last and Final Step :
Getting rid of Stealth Code !

All these can AND should be handled by "modifier" and not need specific method in Game Objects, Specialization could give the according abilities, that would act as a passive ability for some effect needing it, with the level computed from spec level or character level...

Yes I think Blocking could be an "hidden" spell effect, there is pretty much no weapon skill computing in there, all that matter are shield spec level / dex property, Attackers amount, Attacker/Defender Level difference, Size of the shield...

I may be wrong but I don't think any parameter from the "close-combat damage calc" are used for Blocking matter ! Maybe previous-Style Bonus/Malus... But guess what, these are more like buffs ! I Think it should only need some "AttackData" with an attack resulting in a hit to try blocking it...

This kind of coding should apply to most of other "hardcoded" Effects ! (Berserk Malus, Hero transform, QuickCast !!)

I'll keep you update ;)
User avatar
Leodagan
Developer
 
Posts: 1350
Joined: Tue May 01, 2012 9:30 am
Website: https://daoc.freyad.net
Location: Lyon

Re: Spell Revamp Campain.

Postby Leodagan » Tue Nov 04, 2014 7:52 pm

I'll be multi-posting to keep some notes, I don't really have any other "project manager" :)

So for actual need of a clean spell implementation

Living Trying to cast a spell (CastSpell() Method) should gather any data needed for starting the cast sequence (Spell created from spell handler with spell line or object or ability reference ? Some Cast time with computing from propertycalc ?)

Then throw a "Casting Spell Event", When Cast sequence can begin (even for insta) a "Casting Begin Event" should be issued, similar event should be sent for cast finish (even on interrupt), then for more fine grained "spell effect", I think we should need an "Effect Start Event" and an "Effect End Event", we may already have some of these.

I will use live example to explain the needs :

Quickcast, need to set the cast to a steady 2s after the spell has been "required" but is not casting.
Heal, needs to consume power when effect is starting successfully.
Flute Mezz, needs to stop the song after effect landed successfully.
Master Level Target Change (Heal to AOE, Nuke to AoE) needs to act between spell casting and effect starting.
Necromancer Cast, needs to know when the pet is really casting to consume power, this is triggered as a subspell effect.
Heretic Ramping Spell, needs some event for effect pulse.
(I lack some examples...)

For most spell "effect" implementation we need events from the living owner, here DOL have pretty much everything we need, event for target change, event for health/power/endurance change, event for movement etc... The Combat Event will be used a lot to change the results of current "swing", for most of my ideas we may need the same kind of event as for spells, begin swing/end swing/swing damaging target/swing applying special spell effect events...



The Spell Data available from database will be used a lot to describe these handlers. The spell properties should always have the same effect, currently too much field are shared for storing custom values !

I'll try to list the ones only needed to handle the basic spell handler :

SpellID : Primary Key
ClientEffect : spell animation
Icon : ...
Name : default display name,
Description : too much redundancy here but I have no better idea for now
Target : Obvious
Range : //
Radius : // (AoE needs Range AND Radius...)
Power : //
CastTime : //
Damage : Is it really needed ? Shouldn't "Value" be used for a "Direct Damage" Type spell ? Damage/Debuff may need to have both these field to work correctly without subspells...
DamageType : Even if the name is confusing it's also the type of non-damaging spell for resist computing.
Type : The Subclass, pretty much needed !
Duration : seems fair
// these field needs some sorting out :)
Frequency : mostly used for DoT
Pulse : is it used for DoT ?? I think it's mainly for songs...
PulsePower : ok !
RecastDelay : needed.
Value : this should be the main field for all "base value" of the spell that will be used to compare stronger effects for example !
Concentration : ok, the "concentration" behavior should be kept in basic behavior
InstrumentRequirement : may be an additional custom field, songs are really exception in the game !! (by songs I mean real pulsing spells needing an instrument)
SpellGroup : this is used for Hybrid spell sorting, honestly I feel like this value should be in lineXspell it has absolutely no meaning for spell !
EffectGroup : ID to match spell effect that should override each other, I don't like this one too, this field is used to match spell of which "Type" doesn't handle "effect overriding" well.. I'm sure there are some specific case where this field is REALLY needed, but I think most of "overriding" effect should be handled using the Spellhandler Subclass Tree, this way all spell matching a common "subclass" will still be able to override each other :)
SubSpellID : no no no no ! I'm definitely saying no here :) This is a single reference ID, which doesn't allow chaining to prevent any infinite loop, a lot of spell still doesn't need subspell, and some "link table" should be better for this behavior, potions spells and other composite spells (Heretic Rez) show that only ONE subspell may not be enough, this may have been used to delve spell correctly live-like, but with actual tooltip incoming the spell delving will be changed a lot anyway :)
This is still pretty much easy to handle most of subspell, I don't know If I'll get rid of it...
MoveCast : needed
Uninterruptible : needed
SharedTimerGroup : needed
isFocus : needed
Tooltipid : needed

I get rid of specific Warlok field isPrimary, IsSecondary, AllowBolt, I don't even know If I'll re-implement the old "Warlock" behavior with all the change he's been through now ! I would say that's tempting to throw all the "Chamber" away, But Chamber should be a good "Proof of Concept" of the new customization that would allow the spell handlers :)
User avatar
Leodagan
Developer
 
Posts: 1350
Joined: Tue May 01, 2012 9:30 am
Website: https://daoc.freyad.net
Location: Lyon

Re: Spell Revamp Campain.

Postby Graveen » Thu Nov 06, 2014 12:19 pm

:) read !

I agree for subspellid.
Image
* pm me to contribute in Dawn of Light: code, database *
User avatar
Graveen
Project Leader
 
Posts: 12660
Joined: Fri Oct 19, 2007 9:22 pm
Location: France

Re: Spell Revamp Campain.

Postby Leodagan » Thu Nov 06, 2014 12:41 pm

Thanks Graveen for following my work ;)

You agree on Subspellid in which way ? :D

About SubspellID I'm saying that it's pretty damn easy to manage, but it's not fit for every use case and it's ugly regarding database norms (relation 1,n shouldn't be done like this)

So I was wondering if I should remove it and use a link table, or keep it for most Post-Shrouded Isles Classes (every necro or animist related spells just need 1 subspell as they are "container" and not "spell-chain"), and only use some "custom properties" for newer spell that need to link multiple spells ? :D

---------

I make a dual "sided" post, when replying to you I just had an idea about "container" spells, and I even think it's already used in some cases...

Why not use a specific "SpellHandlerContainer", like "PetSpell", in this type of spell handler the "value" is useless, the "primary" spell is mostly an "order-only" effect (spawning a bomber, ordering pet to cast a spell...), so in this specific "Giving Order" Spell the Value field should be a reference to Subspell

I know the Value field being a reference won't help when joining tables, but anyway most "subspellID" need a custom behavior actually, Bomber, PetSpell, and other spells of the same type aren't triggering "Subspells" like other spell handlers...

They are not "multi-spell" they behave more like "composite spell" (a standard spellhandler that have no specific handling for "subspellid" will only trigger subspellID effect at the same time the "primary spell" is successfully applying to target, no other weird behaviors !)

So we keep the "easy" part of having a reference straight inside the Spell Table for these handlers that are meaningless without their subspell, and I implement a standard "multi-spell" behavior when linking spell with a real 1,n link table...

The only doubt I have is that I can't think of any "PetSpell" or "BomberSpell" or similar spell that could NEED the Value field for other behavior ?
User avatar
Leodagan
Developer
 
Posts: 1350
Joined: Tue May 01, 2012 9:30 am
Website: https://daoc.freyad.net
Location: Lyon

Re: Spell Revamp Campain.

Postby Graveen » Thu Nov 06, 2014 6:04 pm

I agree the subspell is awful, where a composite spell mode would rock :)
Image
* pm me to contribute in Dawn of Light: code, database *
User avatar
Graveen
Project Leader
 
Posts: 12660
Joined: Fri Oct 19, 2007 9:22 pm
Location: France

Re: Spell Revamp Campain.

Postby Leodagan » Thu Nov 06, 2014 6:59 pm

You know I'm still not building a composite spell system ? :D

From the work I've already done (targeting the most WEIRD spells I could find in the game) there is pretty much no need of real "composite" spells for live like behavior, the most composite I will use will be multi-spell (one spell trigger "N" effects...) or container-spell (master spell handling special casting from a child spell, the child spell can be a multi-spell itself or anything else)

This would still enable a lot of customization, but I won't put too much effort in allowing multi-effect that works "together", we already talk about the "life drain" example that can't be easily implemented as a Nuke+Heal, it could be implemented as a Nuke+Drain, but the drain effect would have to be a special case of "spell" that can only work as "sub spell" (or it may be a real spell that can Drain Life but without doing damage ? this will mean both Nuke and Drain need their own damage calc, that doesn't make sense...)

on the other side ONE developer can still implement a special subclass of SpellHandler that would use "Custom Properties" as Class Type for instantiating their own spell compositing engine (expecting a specified Interface as sub-effect class handlers), but if anyone is crazy enough to take this way I already warn them about handling the correct values of "isPositiveSpell", "Shearable" and other "virtual properties" that are needed by GameServerRules to tell apart who can attack who ;)
User avatar
Leodagan
Developer
 
Posts: 1350
Joined: Tue May 01, 2012 9:30 am
Website: https://daoc.freyad.net
Location: Lyon

Re: Spell Revamp Campain.

Postby Dinberg » Fri Nov 07, 2014 10:03 am

Hi Leodagan,

Is there any way you can maintain the possibility to write hard-coded spells? ie, the old system can run alongside the new, perhaps via some interface class?
The Marvelous Contraption begins to stir...
User avatar
Dinberg
Inactive Staff Member
 
Posts: 4695
Joined: Sat Mar 10, 2007 9:47 am
Yahoo Messenger: dinberg_darktouch
Location: Jordheim

Re: Spell Revamp Campain.

Postby Leodagan » Fri Nov 07, 2014 10:42 am

Well the thing about hard coded is that it will always work :D

That is whats mean "hardcoded", a "hardcoded" heal spell will just override "onEffectStart()" to add Spell.Value to Target Health, I can't do anything against that, even If I set the spell handers to work only on "event" someone writing such "hardcoded" method will always be able to provide a working spell :)

That's how most spellhandlers have been built, and that's what I want to change at least for the "live" spell base, for other custom spell type I can only provide "tools" but can't force devs to use them :)

I won't really change how the "base" spell handler work (it's confusing to talk about this, I mean the SpellHandler.cs file will keep most methods, and ISpellHandler interface won't change too much), but I will re-work all the Subclass Tree of current Spells...

Typical example, Nuke should be a subclass of "spellhandler" which trigger damage on effect start, DoT should be a subclass of Nuke that trigger damage on effect start with a pulsing effect, Bleed should be a DoT subclass that adds a regen life debuff, Heretic Ramping DoT should be a subclass of DoT with increasing Effectiveness handler, life drain is a subclass of Nuke, etc etc...

Actually a lot of spells doesn't obey this simple subclassing logic, which forces developer to copy/paste code from other spell handlers to "mix behavior", and this can cause trouble in handling effects overriding each other... (which need the special use of Effect ID inside Database to match spell type that aren't in the same Heritage Tree...)

Actually there is a lot of hardcoded check around spells like :

if (SpellType == "DirectDamage" || SpellType == "BomberSpell" || SpellType == "Archery" ...)
{
// this is an offensive Spell yeah !
}

I really want to change this to :

if (SpellHandler is DamageSpellHandler)
{
// I know that ALL subclasses of DamageSpellHandler will match and I'm sure to match "Damaging" Spell.
}
User avatar
Leodagan
Developer
 
Posts: 1350
Joined: Tue May 01, 2012 9:30 am
Website: https://daoc.freyad.net
Location: Lyon

Re: Spell Revamp Campain.

Postby Dinberg » Sun Nov 09, 2014 8:41 pm

Cool, just wanted to check :)

It might be a good idea to use interfaces for this type of check? For example, Bolt spells are also 'damaging' spells but calculate damage differently to DD spells. Wouldn't IDamageSpellHandler be more appropriate in this case to facilitate spells that do not inherit from that DD class?
The Marvelous Contraption begins to stir...
User avatar
Dinberg
Inactive Staff Member
 
Posts: 4695
Joined: Sat Mar 10, 2007 9:47 am
Yahoo Messenger: dinberg_darktouch
Location: Jordheim

Re: Spell Revamp Campain.

Postby Leodagan » Sun Nov 09, 2014 8:51 pm

If Bolt cannot use DirectDamageSpell in its inheritance tree, then both Bolt and DirectDamageSpell should inherit from a DamagingSpellHandler, which could be abstract or use a "default" damage calc, so we still have a "common class"

I don't think interface will be needed, this type of checks are mostly for rules, not to call specific methods :) (or if you match a DamagingAbstractSpellHandler you should at least know that when calling spell.EffectStart() you will trigger damages...)
User avatar
Leodagan
Developer
 
Posts: 1350
Joined: Tue May 01, 2012 9:30 am
Website: https://daoc.freyad.net
Location: Lyon

Re: Spell Revamp Campain.

Postby Dinberg » Mon Nov 10, 2014 8:49 pm

However, bolt and direct damage are fundamentally different in the ways they deal damage - Direct damage effects are dealt instantly, while bolts have a time delay, and use a different method to calculate base damage and variance.

What I mean is the abstract base class would have no common logic in it - so isnt an interface more suitable?
I don't think interface will be needed, this type of checks are mostly for rules, not to call specific methods :) (or if you match a DamagingAbstractSpellHandler you should at least know that when calling spell.EffectStart() you will trigger damages...)
Isn't this again a point pro-interface rather than supporting an abstract class?
The Marvelous Contraption begins to stir...
User avatar
Dinberg
Inactive Staff Member
 
Posts: 4695
Joined: Sat Mar 10, 2007 9:47 am
Yahoo Messenger: dinberg_darktouch
Location: Jordheim

Re: Spell Revamp Campain.

Postby Leodagan » Tue Nov 11, 2014 8:15 am

In fact I reviewed some of my updates, I did this in the beginning of the year I didn't remembered everything :)

I use some interface indeed, but not to tell apart the spell "Type", I used interface to describe specific behavior of "standard" spell, thus I have "IBoltSpellHandler", "IRaisingSpellHandler", "IRangeDisabledSpellHandler", implementing these interface allows to add a behavior component to any "SpellHandler".

This is used for Bolt Heal for example, Archery is also implementing Bolt Interface, Heretic Spell are implementing "Raising Spell" Interface and can subclass any effect this way (Even Raising Debuff etc...), RangeSpellHandler Interface is for limited range buff (like Friar Defensive Heal Proc, which isn't enabled if you're 2000 unit away from the caster)

These Interfaces comes with specific "Helper" Object, "BoltSpellHelper", "IncreasingSpellHelper" etc...
These Helper can be instanciated with a spellhandler, and "extend" the abilities of the given spell handler to implement the Interface methods, you just need some "Entry point" in your object
Code: Select all
BoltSpellHelper BoltHelper = new BoltSpellHelper(this); public void IBoltSpellHandler.StartBoltSpell() { this.BoltHelper.StartBoltSpell(); }
BoltHelper for example will need a SpellHandler Implementing IBoltSpellHandler to be fully functional and start the correct methods after it's OWN timer and Animation methods have finished :)

This is the best way I researched on C# documentation to make "pseudo Multi-Heritage"
User avatar
Leodagan
Developer
 
Posts: 1350
Joined: Tue May 01, 2012 9:30 am
Website: https://daoc.freyad.net
Location: Lyon

Re: Spell Revamp Campain.

Postby Dinberg » Tue Nov 11, 2014 9:42 pm

I find this approach interesting, I like it - describing the individual facets of a spell as objects rather than the whole spell itself.
The Marvelous Contraption begins to stir...
User avatar
Dinberg
Inactive Staff Member
 
Posts: 4695
Joined: Sat Mar 10, 2007 9:47 am
Yahoo Messenger: dinberg_darktouch
Location: Jordheim

Re: Spell Revamp Campain.

Postby Leodagan » Sat Jan 31, 2015 10:01 am

Ok So this have been some time I haven't work in this Area...

It is in fact needed for most compatibility with latest version (especially in the tooltip area, and newer version doesn't handle Text Delve)

One of my first move isn't really targeted to spell but to Abilities...

Abilities are mostly working like "Hard Coded" Spells, some add stats, some trigger offensive spell, some offer instant cure/heal or any other effects...

Actually some Abilities are implemented as "Spell Casting Ability" which allow to link them to a Spell ID which will be used when trying to use the Ability

The bad part is that there is no Data Link between the Ability and it's Spell, and the Spell ID is reserved in C# Code so you have to obey it or it will fail...

I'm trying to bring a new kind of "Spell Casting Ability" that will allow to be used with logical Data Link and enable much easier customization.

The first "Proof of Concept" I tried around this is Linking "Ability" to a "Spell Line" instead of a Spell ID, simply relying on "Ability.KeyName" == "SpellLine.KeyName", these are database unique key and their behavior can be modified by using different "Display Name" (thus if you need to create duplicate Ability that Display "Strength Increase" you can use different KeyName but same Display Name !)

So Any Ability based on "Spell Line Ability" will match their "Effect" by linking the according Spell Line and checking which spell is available to "Ability.Level", this way you can implement Leveling Ability directly using Data record

Example :

"Augmented Strengh" Ability will link "Augmented Strength" Spell Line, this Spell Line will Link with Spells "StrengthAbilityBuff" that increase the AbilityBonus Category instead of regular Base/Spec Stat Buff Category
At Level 0 the "Augmented Strength" Spell Line doesn't Link any spell, thus being ineffective
At Level 1 it targets a first Spell with Type "StrengthAbilityBuff" that offers +4 STR
At Level 2 it targets a second Spell that offers +8 STR
At Level 3 it targets a third Spell that offers +12 STR
[...]

Active Example :
"Master of The Hunt" Ability link with "Master of The Hunt" Spell Line, Linking with specific Master of The Hunt Spell "Shape Change + Max Health Buff + Heal"
Level 1 - 20%
Level 2 - 30%
Level 3 - 40%
Level 4 - 50%

It could need some Spell Handler Update to handle correctly disabling the "Spell Casting Ability" using the Spell Disabled Duration, and there is pretty much no way to check for sure that a spell "landed" or "failed" to enable the disabled timer from "outside" SpellHandler Class.

And for sure it will need some work to implement most Ability as "SpellHandler" relying pretty much on Event Handler instead of Hard Coded "HasAbility(Contants.Ability*****)", and use some specific subclass that allow to cast spell in specific situation like "Purge" that can be casted even if crowd controlled...

This is not just for "Fancy" Ability Code, even if I like the idea of getting rid of most of Ability Code that try to "Mimic" spellhandler but implementing their own rule, In newer version Ability that rely on Spells Effect (typically Active Ability) are delved in Tooltip as "Spells" !

Most Tooltips from Ability/Realm Ability are in fact using a "link ID" to display a "Spell Tooltip Delve", the client use something like "Purge Ability ID 111 => Spell ID 222" then request tooltip for Spell ID 222 which must match the Behavior of the Ability !

And the other constraint is that ANY Icon displayed in Player Buff/Debuff Bar MUST be a Spell Effect, the client doesn't handle any other Tooltip "Type" for Player Effects so anything triggering effects must be using a Spell !

The only workaround for "Hard-Coded" Effect like most Ability Effect is to send a disabled tooltip in Spell Effect (ID: 0 will mostly not return any Data), but that also disable the ability to "Cancel" the Effect, so you can't Cancel Anymore your Berserk or Stage Form or any Self-Positive Ability

In fact the "Tooltip ID" is using the Old "Effect ID" Packet Code which was a unique code for each Effect to match player "Cancel Request ID", now this ID can't be uniquely generated and must match some data records to display according Delve and Allow Canceling !
User avatar
Leodagan
Developer
 
Posts: 1350
Joined: Tue May 01, 2012 9:30 am
Website: https://daoc.freyad.net
Location: Lyon

Re: Spell Revamp Campain.

Postby Leodagan » Tue May 19, 2015 12:41 pm

I lately found some handler in GamePlayer to allow Casting an Item Spell (From /use command) allowing for an unlimited chaining of recursive subspellID...

This was using specific Casting Handler within Gameplayer class, I couldn't bear it and had to disable this behavior as being "Dangerous" (no real check for infinite recursivity) , and not being at the right place... (Spell Handling should be in Spell HANDLER !)

for this Revision 3479 here is the change log
Code: Select all
7b43ad29737c11ccae50cfa20b94d707fc96bd47 .../trunk/GameServer/gameobjects/GamePlayer.cs | 3 -- DOLSharp/trunk/GameServer/spells/SpellHandler.cs | 47 ++++------------------ 2 files changed, 8 insertions(+), 42 deletions(-) diff --git a/DOLSharp/trunk/GameServer/gameobjects/GamePlayer.cs b/DOLSharp/trunk/GameServer/gameobjects/GamePlayer.cs index b560396..887af9a 100644 --- a/DOLSharp/trunk/GameServer/gameobjects/GamePlayer.cs +++ b/DOLSharp/trunk/GameServer/gameobjects/GamePlayer.cs @@ -9268,9 +9268,6 @@ namespace DOL.GS //Spell if (spellHandler.StartSpell(target, useItem)) { - //SubSpells - spellHandler.CastSubSpells(target, spellHandler.SpellLine); - if (useItem.Count > 1) { Inventory.RemoveCountFromStack(useItem, 1); diff --git a/DOLSharp/trunk/GameServer/spells/SpellHandler.cs b/DOLSharp/trunk/GameServer/spells/SpellHandler.cs index dea7e48..821bb6a 100644 --- a/DOLSharp/trunk/GameServer/spells/SpellHandler.cs +++ b/DOLSharp/trunk/GameServer/spells/SpellHandler.cs @@ -246,18 +246,6 @@ namespace DOL.GS.Spells } StartSpell(m_spellTarget); - - if (m_spell.SubSpellID > 0 && Spell.SpellType != "Archery" && Spell.SpellType != "Bomber" && Spell.SpellType != "SummonAnimistFnF" && Spell.SpellType != "SummonAnimistPet" && Spell.SpellType != "Grapple") - { - Spell spell = SkillBase.GetSpellByID(m_spell.SubSpellID); - //we need subspell ID to be 0, we don't want spells linking off the subspell - if (spell != null && spell.SubSpellID == 0) - { - ISpellHandler spellhandler = ScriptMgr.CreateSpellHandler(m_caster, spell, SkillBase.GetSpellLine(GlobalSpellsLines.Reserved_Spells)); - spellhandler.StartSpell(m_spellTarget); - } - } - } else { @@ -1879,19 +1867,6 @@ namespace DOL.GS.Spells effect.Cancel(false); } - - //Subspells - if (m_spell.SubSpellID > 0 && Spell.SpellType != "Archery" && Spell.SpellType != "Bomber" && Spell.SpellType != "SummonAnimistFnF" && Spell.SpellType != "SummonAnimistPet" && Spell.SpellType != "Grapple") - { - Spell spell = SkillBase.GetSpellByID(m_spell.SubSpellID); - //we need subspell ID to be 0, we don't want spells linking off the subspell - if (target != null && spell != null && spell.SubSpellID == 0) - { - ISpellHandler spellhandler = ScriptMgr.CreateSpellHandler(m_caster, spell, SkillBase.GetSpellLine(GlobalSpellsLines.Reserved_Spells)); - spellhandler.StartSpell(target); - } - } - //the quick cast is unallowed whenever you miss the spell //set the time when casting to can not quickcast during a minimum time if (m_caster is GamePlayer) @@ -2352,23 +2327,16 @@ namespace DOL.GS.Spells /// Cast all subspell recursively /// </summary> /// <param name="target"></param> - public void CastSubSpells(GameLiving target, SpellLine line) + public virtual void CastSubSpells(GameLiving target) { - if (Spell.SubSpellID > 0 && Spell.SpellType != "Archery" && Spell.SpellType != "Bomber" && Spell.SpellType != "SummonAnimistFnF" && Spell.SpellType != "SummonAnimistPet" && Spell.SpellType != "Grapple") + if (m_spell.SubSpellID > 0 && Spell.SpellType != "Archery" && Spell.SpellType != "Bomber" && Spell.SpellType != "SummonAnimistFnF" && Spell.SpellType != "SummonAnimistPet" && Spell.SpellType != "Grapple") { - List<Spell> spells = SkillBase.GetSpellList(SpellLine.KeyName); - foreach (Spell subSpell in spells) + Spell spell = SkillBase.GetSpellByID(m_spell.SubSpellID); + //we need subspell ID to be 0, we don't want spells linking off the subspell + if (target != null && spell != null && spell.SubSpellID == 0) { - if (subSpell.ID == Spell.SubSpellID) - { - SpellHandler subSpellHandler = ScriptMgr.CreateSpellHandler(Caster, subSpell, line) as SpellHandler; - if (subSpellHandler != null) - { - subSpellHandler.StartSpell(target); - subSpellHandler.CastSubSpells(target, line); - } - break; - } + ISpellHandler spellhandler = ScriptMgr.CreateSpellHandler(m_caster, spell, SkillBase.GetSpellLine(GlobalSpellsLines.Reserved_Spells)); + spellhandler.StartSpell(target); } } } @@ -2494,6 +2462,7 @@ namespace DOL.GS.Spells ApplyEffectOnTarget(null, 1); } + CastSubSpells(target); return true; } /// <summary>
As most of the time I'm deleting Code instead of Adding :D

On Storm I found the given SpellHandler that use more than one Chained "SubSpell"
Code: Select all
140760 Reanimate Corpse 140770 140770 Summon Monster 140790 140790 Monster Dot 0 NULL NULL NULL 140780 Monster Disease 140780 140780 Monster Disease 140780 140780 Monster Disease 140780 140780 Monster Disease 140780 30136 Curse of the Scarab 30138 30138 NearSight 30135 30135 Snare NULL NULL NULL NULL 14076 Reanimate Corpse 14078 14078 Summon Monster 14079 14079 Monster Disease 14077 14077 Monster Dot 0 14078 Summon Monster 14079 14079 Monster Disease 14077 14077 Monster Dot 0 NULL NULL NULL 11436 Sporespawn Seedling 11401 11401 Sporespawn Seedling 11401 11401 Sporespawn Seedling 11401 11401 Sporespawn Seedling 11401 11401 Sporespawn Seedling 11401 11401 Sporespawn Seedling 11401 11401 Sporespawn Seedling 11401 11401 Sporespawn Seedling 11401
Appart from Reanimate Corpse and Curse of Scarab the other are infinite recursive bug...

Storm is clearly Lacking the "Hero" Buff Potion that can trigger a full buff chain, and I wonder if the specific item /use method in GamePlayer was made for Curse of Scarab or other Shard implementing Multiple Buff Potions !

Anyway I intend to add a new kind of "Proof of Concept", using the newly created "SpellXCustomValues" mechanisms to implement "Multiple Subspell ID" Chaining in a safe way, attaching directly an "Array of Subspell" to a single spell, and not using Spell Chaining !

... to be continued
User avatar
Leodagan
Developer
 
Posts: 1350
Joined: Tue May 01, 2012 9:30 am
Website: https://daoc.freyad.net
Location: Lyon


Return to “%s” DOL Development Discussion

Who is online

Users browsing this forum: No registered users and 1 guest