Aller au contenu

Photo

Custom Quick Item - destroyed after 1 use - how to fix?


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

#1
Innodil Ath Nathosh

Innodil Ath Nathosh
  • Members
  • 28 messages
 OK, Here's the thing:

- Created ABI_teleport.gda, copied over "ITEM_UNIQUE_POWER_UNLIMITED_USE" and changed name etc.
- Changed script from "item_unique_power" to "item_inno_teleport"
- Created item resource, base type "other - quick item", ability "ITEM_TELEPORT"
- exported
- run game
- use item --> works like a charm

BUT: After the first use, my item's gone!
Before I actually used the UNIQUE_POWER thing, but that script just fires the event into your module script and I wanted to remove that coupling.
However, the item was not being destroyed when I used that ability type.

After searching the wiki I found that: (http://social.biowar.../index.php/Item)

Activated Items
Each item can have a single default action. This is entered by picking an ability of type "Item Ability" from the abilities table which defines its icon, script, description and targetting behaviour. Items that can be used go into a special equip slot. All other item types (weapons, armor, et cetera) cannot have a custom item use. The number of uses for this ability will be decided by the script which will destroy the item when appropriate.
there are no uses per day type items. All items only have "number of uses".

Obviously I am NOT destroying my item in script...

Other stuff I tried:
- setting item as plot item -> I can't use it anymore at all, I can't also not move it to the quickbar anymore.
- using the SetItemIndesctructible() function -> no change, item still removed after use
- actually using ITEM_UNIQUE_POWER_UNLIMITED_USE as ability and moving my script to the module script --> item works as expected and is not destroyed after use--> WTF? I search the core scripts and 2DA files for hours but there is NOTHING to indicate this ability is handled any differently! Some bioware guy--> please explain?

Below my script for reference:

/*
 * inno_item_teleport - ITEM_TELEPORT ability script. See ABI_base_teleport 2DA.
 *
 */
#include "abi_templates"
#include "inno_teleport_h"

void _HandleImpact(struct EventSpellScriptImpactStruct stEvent, object oItem)
{
	Teleport(oItem);
}

void main()
{
	event ev = GetCurrentEvent();
	int nEventType = GetEventType(ev);

	switch(nEventType)
	{
		case EVENT_TYPE_SPELLSCRIPT_PENDING:
		{
			Ability_SetSpellscriptPendingEventResult(COMMAND_RESULT_SUCCESS);
			break;
		}

		case EVENT_TYPE_SPELLSCRIPT_CAST:
		{
			struct EventSpellScriptCastStruct stEvent = Events_GetEventSpellScriptCastParameters(ev);
			SetAbilityResult(stEvent.oCaster, stEvent.nResistanceCheckResult);
			break;
		}

		case EVENT_TYPE_SPELLSCRIPT_IMPACT:
		{
			// Get a structure with the event parameters
			struct EventSpellScriptImpactStruct stEvent = Events_GetEventSpellScriptImpactParameters(ev);
			Log_Trace(LOG_CHANNEL_COMBAT_ABILITY, GetCurrentScriptName() + ".EVENT_TYPE_SPELLSCRIPT_IMPACT",Log_GetAbilityNameById(stEvent.nAbility));
			//get object
			object oItem = GetEventObject(ev, 2);

			// Handle impact
			_HandleImpact(stEvent, oItem);
			break;
		}
	}
}


Any clues anyone?

#2
sillyrobot

sillyrobot
  • Members
  • 171 messages
The short answer is you can't (don't worry there is a better answer). The game has a hard-coded removal of items on use unless the item ability used is UNIQUE_POWER_UNLIMITED, Kolgrim's Horn, or I think one other case.

The better answer is to cheat. Make your item stackable. Then in the cast event add one to the stack size. The impact event will reduce the stack size by one, and voila!

Another alternative is to make teh ability of a type other than item. That has other ramification though like can it be used with stealth, can it be dispelled, etc.

Here's my case from my Bag of Beans

        case EVENT_TYPE_SPELLSCRIPT_CAST:
        {
            // I can't find the item reference in the ev object so let's find it the hard way
            object oItem = GetItemPossessedBy( GetHero(), "BagOfBeans" );
            SetItemStackSize( oItem, 1 + GetItemStackSize( oItem )); // bypasses the hardcoded stack reduction
            struct EventSpellScriptCastStruct stEvent = Events_GetEventSpellScriptCastParameters(ev);
            SetAbilityResult(stEvent.oCaster, stEvent.nResistanceCheckResult);
            break;
        }

Modifié par sillyrobot, 02 janvier 2010 - 10:01 .


#3
Innodil Ath Nathosh

Innodil Ath Nathosh
  • Members
  • 28 messages
This is why I hate modding for DA:O... frecking undocumented hardcoded crap. I don't get how this is designed. How hard is it to add a column to some 2DA with "unlimiteduse" or something anyway?



Anyway: Thanks alot for this insightful answer, I'm glad it's not ME who was screwing up ;-)

And thanks for the stack trick I think I'll just go for that one...still beats having to add a module script for your items :) I considered creating a skill for it, but that's just too much work

#4
Innodil Ath Nathosh

Innodil Ath Nathosh
  • Members
  • 28 messages
@sillyrobot: a tip :), in EVENT_TYPE_SPELLSCRIPT_IMPACT you CAN get your item from the event, and your stack trick works there too (I didn't want to hardcode my item tag cause I need it to be generic so I played around abit...)



Like this:

//get object

object oItem = GetEventObject(ev, 2);

#5
sillyrobot

sillyrobot
  • Members
  • 171 messages
Thanks. I wasn't sure if the Impact event was fired before or after the stack reduction. By the time I found the hard-code, I just wanted a fix. I'll shift the stack boost down to impact.

#6
kilrex

kilrex
  • Members
  • 69 messages
OPTION1: (I use this for some things)
call the code to do the object's effect at the PENDING event and don't do anything else with the event.
More specifically, it is this line that results in your item being removed

SetAbilityResult(stEvent.oCaster, stEvent.nResistanceCheckResult);

Basically do nothing for the CAST and IMPACT
events, and run you impact method in the PENDING event.

The one drawback to this is, once one character uses the item, it is marked as unusable for any other character.

Since so much of things aren't documented, I don't know why this is so.


OPTION2:
Another option is to use the code you have, and in your _handle_impact, give yourself a new instace of the object.

At the end of the IMPACT event, add a new copy of the item back to your inventory.

UT_AddItemToInventory(R"YOUR_ITEM.uti", 1);