Question about World Events and Messages in Skrit
Submitted by Lloyd2k4 on Thu, 2014-01-16 13:05 | ||
Currently, I'm trying to complete a skrit that implements critical strikes in the game for all weapon types I decide to attach the skrit to. I'm having some trouble with what Events and messages I should be looking for, though, in order for the skrit to process to each state correctly. First off, I have no idea what world event or message I should be looking for in order to begin getting into the skrit's states beyond startup. Does anyone know what event/message is being sent by the game when you begin an attack in melee or ranged? Does the weapon you used to attack also get a message when the attack lands/doesn't land? If I can't figure this out soon with trial and error (the Help log files aren't descriptive enough...), I'm going to have to implement Witness's skrit Listen so I can see all the messages being sent and received on the object I attach it too, because I'm at a loss when it comes to weapon. With spells and the actors, it's very easy to figure out what messages you need... but this is for the weapon itself. The weapon is the GoSkritComponent, so I need to know what messages/events are happening with the weapon, not the actor or target. forums: |
||
» |
Can't look at files since tank viewer no longer works for me, but you may try searching in world/ai/jobs as a starting point.
Theresnothinglft did this in his SOT3k Weapon Packs, as well as implementing multiple hit weapons.
I did a quick search here and also elsewhere for a copy and couldn't find one so I've linked the version I have got.
http://www.siegetheday.org/~iryan/files/sot3kwp3.dsres (2.55Mb)
http://www.siegetheday.org/~iryan/files/sot3kwp3_readme.txt
I know this is open source as long as due credit is given and I used the models from here in DS2BW Adepts. If you untank the mod and look around inside I'm certain you'll find something to help you in your endeavours.
Incidentally since this mod isn't available here maybe a moderator would like to add it to the downloads section.
Got my skrit to work! Here is the code for anyone curious:
//////////////////////////////////////////////////////////////////////// // // File : weapon_critical.skrit // Author(s): Lloyd2k4, theresnothinglft // // Add critical strike chance to weapons based on dexterity (optional) ///////////////////////////////////////////////////////////////////////
property bool _server_only$ = false;
property float crit_chance$ = 0.0 doc = "Base chance to crit before Dexterity modifier.";
property float dex_multiplier$ = 0.0 doc = "Multiply actor's Dex by this amount and add to crit_chance.";
property float crit_multiplier$ = 2.0 doc = "Multiply damage done by this amount when a crit happens.";
owner = GoSkritComponent;
Goid attacker$;
Goid target$;
startup state idle$
{
event onGoHandleMessage$( eWorldEvent e$, WorldMessage msg$ )
{
if( owner.Go.parent != null )
{
if( owner.Go.parent.isActor() )
{
if( owner.Go.isEquipped() )
{
attacker$ = owner.Go.parent.goid;
setstate Attack$;
}
}
}
}
}
state Attack$
{
event onEnterState$
{
godb.startwatching( owner.goid, attacker$ );
}
event OnGoHandleCCMessage$( eWorldEvent e$, WorldMessage msg$ )
{
if( !owner.Go.isEquipped() )
{
godb.stopwatching( owner.Goid, attacker$ );
setstate idle$;
}
if( e$ == WE_ANIM_WEAPON_FIRE )
{
Job action$ = attacker$.Go.Mind.GetFrontJob( JQ_ACTION );
if( action$ != NULL )
{
if( action$.JobAbstractType == JAT_ATTACK_OBJECT_MELEE || action$.JobAbstractType == JAT_ATTACK_OBJECT_RANGED )
{
target$ = action$.goalobject;
if( target$ != null && target$ != attacker$ )
{
SetState DamageTarget$;
}
}
}
}
}
}
state DamageTarget$
{
trigger onGoHandleCCMessage$( WE_ENGAGED_HIT_LIVED )
{
float dex$ = attacker$.Go.Actor.GetSkillLevel("dexterity") - 10; // get the dex of actor using our object
float chance$ = ( ( dex$ * dex_multiplier$ ) / 100 ) + crit_chance$; // calculate our go's chance to crit
float random$ = Math.RandomFloat( 1.0 ); // roll for crit!
// is the random # we rolled less than or equal to our chance to crit?
if( random$ <= chance$ )
{
float damage$ = Math.RandomFloat( owner.Go.Attack.DamageMin, owner.Go.Attack.DamageMax ) * ( crit_multiplier$ - 1.0 );
Rules.DamageGo( target$, attacker$, owner.Goid, damage$, false, false );
Rules.AwardExperience( attacker$, owner.Goid, Rules.CalculateExperience( attacker$, owner.Goid, target$, damage$ ) );
Report.SScreen( attacker$.Go.Player.MachineId, "Critical Hit!" );
setstate Finish$;
}
else
{
setstate Finish$;
}
}
}
state Finish$
{
event OnEnterState$
{
godb.stopwatching( owner.goid, attacker$ );
setState idle$;
}
}
The skrit calculates our chance to critical strike using the base crit chance and the dexterity formula, and then rolls a value in order to see if we crit. If there's a crit, inflict additional damage based on the crit multiplier property, and award experience as necessary. Report in-game that a critical strike has occurred, and return to the beginning of the skrit, waiting for it to start all over again. The code in the first two states is just establishing the parent of the weapon (the player), and that we have a valid target to set as our goal object that we're going to inflict extra damage on in the event of a successful crit roll.