Aller au contenu

Photo

RE: Thrown Weapons - Is This Possible?


  • Veuillez vous connecter pour répondre
31 réponses à ce sujet

#1
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
 Not sure if this is possible...

I have changed throwing axes and darts so that are single stack items that function pretty much identically to their pnp counterparts. I can recover them from corpses just fine, but I can't wrap my head around how to recover them in the case of a miss.

In the event of a miss, Is it possible to create a copy of the item - which the PC can recover later - in a location near the target without using a custom spell script (and thus modifying 2da files)? 

#2
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
hmm, If they are single stacked, Both the unequipted and unaquired event will fire when the item is thrown.

#3
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
Yeah I use the OnUnacquireItem event to store the weapon temporarily on the attacker then I "clone" it in the target's OnDamaged event. At least that's the theory anyway...

Modifié par Pstemarie, 09 février 2013 - 04:25 .


#4
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
Onunaquired, if the pc is in combat, set a local object var on the pc with the local object as the item in mainhand, and delaycommand a check to see if the var, Thrown, is still set a half-second later. In a generic (modwide) ondamaged, check damager for var, and if set, delete. When the delayed var check fires, if the var is still set and the pc, you have a miss, and you can copyobject and setstacksize, placing the item in a spellcone in front of the pc. Only likely issue I can see is getting the timing down - a half second could be too short or to long, though troubleshooting to eliminate other unacquires might take some time and code.

[Edit] Another potential issue is throws that deal no damage, depending on your item props, and depending on how you're planning to handle hits (you said you had that down).

Funky

Modifié par FunkySwerve, 09 février 2013 - 04:24 .


#5
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<noodling...>

How about turning that around... Mark it for cloning on the ground near-by and (if it *doesn't* damage target, clone it there. If it does, clone it in inventory of target.

Edit: Funky's quick! :-)

I'd let determinecombatround do the timing, but, either way, mark it as going *somewhere* and then let OnDamage change the destination from ground (spell cone - nice!) to inventory.

<...negligently>

Modifié par Rolo Kipp, 09 février 2013 - 04:25 .


#6
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<bouncing...>

Heh. If it dealt no damage, the axe bounced off :-)

<...on his toes>

#7
henesua

henesua
  • Members
  • 3 863 messages
I really like this idea, and I'm gonna steal it. :)

#8
Pstemarie

Pstemarie
  • Members
  • 2 745 messages

FunkySwerve wrote...

Onunaquired, if the pc is in combat, set a local object var on the pc with the local object as the item in mainhand, and delaycommand a check to see if the var, Thrown, is still set a half-second later. In a generic (modwide) ondamaged, check damager for var, and if set, delete. When the delayed var check fires, if the var is still set and the pc, you have a miss, and you can copyobject and setstacksize, placing the item in a spellcone in front of the pc. Only likely issue I can see is getting the timing down - a half second could be too short or to long, though troubleshooting to eliminate other unacquires might take some time and code.

[Edit] Another potential issue is throws that deal no damage, depending on your item props, and depending on how you're planning to handle hits (you said you had that down).

Funky


Ye lost me...:blink:

#9
Pstemarie

Pstemarie
  • Members
  • 2 745 messages

henesua wrote...

I really like this idea, and I'm gonna steal it. :)


Good when you figure out the miss part, I'll "steal" it back :bandit:

#10
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<giving props...>

And do the same thing with arrows & bolts, with a chance for "lost" or "broken". :-) Then you can raise the cost of ammunition to something less absurd than 1gp for a hundred! Generate economy ;-)

<...to the poor bowyers>

#11
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
Had to do some adjusting to what I had originally envisioned. Seems that OnDamaged does NOT fire with the killing strike - it jumps right to OnDeath. Furthermore, once you've thrown the last weapon in the stack you can no longer get a valid object. Therefore, I've increased the stack size for darts and throwing axes to 5 and adjusted the costs accordingly. So its basically this for stack sizes...

Darts, Throwing Axes, and Shuriken = 5
Arrows = 10
Bolts and Bullets = 20

Therefore, I've gone with what Sharona Curves posted over in this thread.

Unfortunately, it doesn't allow for misses but I think I'll be able to figure out what Funky was talking about - it makes a little more sense now. :huh:

Modifié par Pstemarie, 09 février 2013 - 09:30 .


#12
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
by making the thrown items stackable, it removes the ability to get the item leaving the player by the unequip and unaquire events. they will only fire when the last item in the stack is used.

Most of what I have been looking at ( off and on ) went with the assumption that the items where no longer stacked.

Let me start some other tests in reguards to the items being stacked. Reguardless you will most likely need to use the OnPhysicalyAttacked event to track the weapon leaving the target. Once 4 attacks per round are reached It will most likely fire only one time per fury.( 3 max furys per round) giving more then one item lost per OnPhysicalyAttacked event.

#13
Pstemarie

Pstemarie
  • Members
  • 2 745 messages

Lightfoot8 wrote...

by making the thrown items stackable, it removes the ability to get the item leaving the player by the unequip and unaquire events. they will only fire when the last item in the stack is used.

Most of what I have been looking at ( off and on ) went with the assumption that the items where no longer stacked.

Let me start some other tests in reguards to the items being stacked. Reguardless you will most likely need to use the OnPhysicalyAttacked event to track the weapon leaving the target. Once 4 attacks per round are reached It will most likely fire only one time per fury.( 3 max furys per round) giving more then one item lost per OnPhysicalyAttacked event.


Gah, sorry I messed you up LF. I can easily revert if you can work something out. 

#14
Failed.Bard

Failed.Bard
  • Members
  • 774 messages
I think I'd set a variable on the PC OnEquip with the ResRef of the thrown item, that you can use for spawning the new object with. You should also store the object, so you can ensure that it was used as a weapon (thrown, and thus is invalid as an object when checked), as opposed to intentionally dropped directly from the hand slot (which could lead to duping exploits if not checked).

I'm not sure if OnPhysicalAttacked fires on misses, but that's still likely the NPC script I'd hook, rather than OnDamaged. However, if GetAttemptedAttackTarget() works for PCs, you could handle all of it from the OnUnaquire script, just creating the weapon on the ground every time instead of in the target creatures inventory.

#15
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
Ok I've got this working now on misses - the OnPhysicalAttacked event was the key.

// Check if oAttacker "missed" the caller with a dart or handaxe attack
object oAttacker = GetLastAttacker();
object oDamager = GetLastDamager();
        SendMessageToPC(GetFirstPC(), GetName(OBJECT_SELF)+ " Attacker = " +GetName(oDamager));
        SendMessageToPC(GetFirstPC(), GetName(OBJECT_SELF)+ " Damager  = " +GetName(oDamager));

        if (oDamager == oAttacker)
        {
            //do nothing - we hit
        }
        else
        {
            object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oAttacker);
            if (GetIsObjectValid(oItem))
            {
                if (GetBaseItemType(oItem) == BASE_ITEM_DART || GetBaseItemType(oItem) == BASE_ITEM_THROWINGAXE)
                {
                    location lLoc = GetRandomLocation(GetArea(OBJECT_SELF), OBJECT_SELF, 3.0);
                    object oThrown = CopyObject(oItem, lLoc);
                    SetItemStackSize(oThrown, 1);
                    SetIdentified(oThrown, 1);
                }
            }
}

The only oddity I've noiticed is that on the first attack oAttacker and oDamager seem to both = OBJECT_INVALID as the SendMessageToPC output is empty.

Modifié par Pstemarie, 09 février 2013 - 11:55 .


#16
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
The final product - used in the OnPhysicalAttacked event to create an item near the target in the event of a miss.

// Check if oAttacker "missed" the caller with a dart or handaxe attack

object oAttacker = GetLastAttacker();

if (GetIsObjectValid(oAttacker) && GetDamageDealtByType(DAMAGE_TYPE_PIERCING) <= 0 || 
    GetDamageDealtByType(DAMAGE_TYPE_SLASHING) <= 0)
{
  object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oAttacker);
  
  // Check the stack size - starting at 2 - to make sure you don't get back more 
  // ammo than you started with
  if (GetIsObjectValid(oItem) && GetItemStackSize(oItem) > 2)
  {
    if (GetBaseItemType(oItem) == BASE_ITEM_DART || GetBaseItemType(oItem) == BASE_ITEM_THROWINGAXE)
    {
       location lLoc = GetRandomLocation(GetArea(OBJECT_SELF), OBJECT_SELF, 3.0);
       object oThrown = CreateObject(OBJECT_TYPE_ITEM, GetResRef(oItem), lLoc);
       SetItemStackSize(oThrown, 1);
       SetIdentified(oThrown, 1);
     }
  }
}

Modifié par Pstemarie, 10 février 2013 - 02:06 .


#17
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
be nice if it was that simple, But you have your events out of order.

OnPhysicalAttacked Event happens first. No damage has yet been done.
If it was the last item in the stack. unequip fires followed by unaquire.
Hit roll then happens
if damage is done then the OnDamage event fires.

Doing everything in the on OnPhysicalAttacked can not catch the damage for the current attack.
At least that is my current understanding.

You are going to need to use more then one event and mostlikely a delayed event to chtch the miss for the current attack

#18
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
Well its working - I've been testing and tweaking for two hours. I had to set the stack size check to >2 because it kept generating one extra item otherwise.

OnPhysicalAttacked only handles a miss while OnDamaged uses Sharona's function to drop the missile in the target's inventory.

I'm not sure why GetDamageDealtByType is catching anything in the OnPhysicalAttacked but my SendMessage debugs - which I removed show 0 damage on a miss. I have run several tests using full stacks and partial stacks with all attacks hitting and all attacks missing. So far everything works.

#19
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
Hmm, Perhaps my understanding is off. If it is you may have come across a great find.

Testing.

#20
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
I have a knack for stumbling onto stuff :blush: Usually I get burned by my "finds", so let's just say I'm waiting for this script to break something else...

I do recall GZ saying something on the old forums about certain function calls being able to rearrange the way events fire, something about priorities and what not. I didn't really understand it, but I think it was why bioware tagged some functions with "Use only this Event" or "Only works in this Event".

The only glitch I have noticed is if you fire the last shot the PC will charge the target. Then if you draw another weapon while charging the PC stops then jumps to the target on the next Heartbeat. Looks like lag to me, but I'm not sure.

Modifié par Pstemarie, 10 février 2013 - 02:26 .


#21
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
Well It is flawed. Take your attacks down to one attack. Attack the target then break off combat. It will be simpler to see what I am talking about.

Your first attack on a target is going to gove you the damage done the attack before. So if the target has not been attacked before the first attack is always going to regester as a miss.

reguardless of wether the next attack hits or misses it is going to use the round before as the indecator of the hit or miss.

#22
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
Ok that explains why it always creates an extra miss item when you intiate the first attack with a dart or hand axe. I think with the hacked "fix" though I can live with it since it only affects darts and throwing axes.

EDIT - Ran some more tests doing what you said. It is flawed like you say, but I can live with it since you never get back more ammo than you threw. At this point I'm really just trying to avoid a PC that throws say 5 handaxes or darts at a target and collects back more than 5 between the monster's corpse and the missed axes lying about the ground. While I did have one test that came up one axe short, the rest have all come up with no more than what the PC started with. So, I'll take what I get and move onto the next hack.

If you can't beat it, hack it :innocent:

Modifié par Pstemarie, 10 février 2013 - 03:20 .


#23
Failed.Bard

Failed.Bard
  • Members
  • 774 messages
Would it work doing it as a subroutine on a 0.01 delay, or would that get messed up worse once multi-attack flurries are taken into account?

#24
Pstemarie

Pstemarie
  • Members
  • 2 745 messages

Failed.Bard wrote...

Would it work doing it as a subroutine on a 0.01 delay, or would that get messed up worse once multi-attack flurries are taken into account?


It seems that any variation from what I have posted in the "final" code above results in too much ammo being created on a miss.

#25
WhiZard

WhiZard
  • Members
  • 1 204 messages

Pstemarie wrote...

Failed.Bard wrote...

Would it work doing it as a subroutine on a 0.01 delay, or would that get messed up worse once multi-attack flurries are taken into account?


It seems that any variation from what I have posted in the "final" code above results in too much ammo being created on a miss.


Try this. In the OnAttacked event for creatures replenish the ammunition for this weapon no matter what.  In the OnDamaged event decrement the ammunition for this weapon by one.  While this won't work in the last flurry for the ammunition, it will accurately distinguish between missing and hitting shots within a flurry.

EDIT: Actually, since the creature can be damaged by spells,  it would be better to replace the OnDamaged decrement with an On Hit decrement given as a unique power to the weapon.

Modifié par WhiZard, 10 février 2013 - 06:39 .