How to extend the APR Base and call it.
#1
Posté 06 avril 2010 - 11:54
I've tried every which way but sunday to do this. I've tried extending itemprps and calling the movementrate effect (8), that simply stops all movement. No matter what adjustments the character won't move, this also happens with movement rate debug(11) btw. It must be a bug or it is simply not intended for item and more for spell effects.
I tried scripting by using effectmodifymovementrate command, also EFFECT_TYPE_MOVEMENT_RATE. Nothing. It simply doesn't work. The character can move, but its not at double speed, no matter what float values I use.
The only way I have been able to double moverate is by creating an APR GDA file that overwrites line 2 & 15 Elf and human, and modifying the movement. Except that is a global effect. I simply want this to turn on only when the armor is equipped.
I've tried extending the APR giving a M2DA number, but that is capped off at like 60,000 or something due to a bug. But either way, extending it is one thing, Now I have figure out how to call that M2DA number when an armor is equipped, in other words when the armor is equipped a new appearance is called, with the higher movement speed.
I don't know if this is possible thru scripting or if its something you can do with itemprps, or properties, effects, etc. I haven't seen anything that would look like it would do this in the xls files, so I'm think this would need to be done in scripting. But I'm not that good at scripting, and I'm not really sure how to go about it.
Any help would be greatly appreciated
#2
Posté 07 avril 2010 - 01:57
void main()
{
event ev = GetCurrentEvent();
int nEventType = GetEventType(ev);
// We will watch for every event type and if the one we need
// appears we will handle it as a special case. We will ignore the rest
// of the events
switch ( nEventType );
case EVENT_TYPE_EQUIP:
{
object oEquipper = GetEventCreator(ev); // The object equipping an item
int nInventorySlot = GetEventInteger(ev, 0); //
int bEquippedByPlayer = GetEventInteger(ev, 1); //
object oItem = GetEventObject(ev, 0); // The item being equipped
int nRace = GetCreatureRacialType(oEquipper);
// HELP!!!!!!!!!
if(nRace == 2) //assumes that apr ID is the return from getcreatureracialtype, but I dunno does anybody know???
SetAppearanceType(oEquipper,65010,FALSE); // sets appearance to m2da 65010 for elf to move at double speed
else if(nRace == 15) //assumes that apr ID is the return from getcreatureracialtype, but I dunno does anybody know???
SetAppearanceType(oEquipper,65011,FALSE); // sets appearance to m2da 65011 for human to move at double speed
break;
}
case EVENT_TYPE_UNEQUIP:
{
object oItem = GetEventCreator(ev); // item being unequipped
int nInventorySlot = GetEventInteger(ev, 0); //
object oCreator = GetEventObject(ev, 0); //
int nRace = GetCreatureRacialType(oEquipper);
// HELP!!!!!
if(nRace == 2) //assumes that apr ID is the return from getcreatureracialtype, but I dunno does anybody know???
SetAppearanceType(oEquipper,2,FALSE); // sets appearance to default for elf to move at normal speed
else if(nRace == 15) //assumes that apr ID is the return from getcreatureracialtype, but I dunno does anybody know???
SetAppearanceType(oEquipper,15,FALSE); // sets appearance to default for human to move at normal speed
break;
}
}
Modifié par mutantspicy, 07 avril 2010 - 02:04 .
#3
Posté 07 avril 2010 - 04:21
At least that's what the game scripts do, but sometimes they just use magic numbers instead.
BTW, APR_ should work up to 65535.
2da_constants_h.nss (side comments added)
const int RACE_INVALID = 0;
const int RACE_DWARF = 1;
const int RACE_ELF = 2;
const int RACE_HUMAN = 3;
const int RACE_QUNARI = 4;
const int RACE_ANIMAL = 5;
const int RACE_BEAST = 6;
const int RACE_DARKSPAWN = 7;
const int RACE_DRAGON = 8;
const int RACE_GOLEM = 9;
const int RACE_SPIRIT = 10; !!! DELETED IN THE 2DA !!!
const int RACE_UNDEAD = 11; !!! CALLED "DEMONS" IN THE 2DA !!! But I believe "undead = possessed by a demon" in DA:O.
Modifié par FollowTheGourd, 07 avril 2010 - 04:30 .
#4
Posté 07 avril 2010 - 05:10
#include "utility_h"
#include "wrappers_h"
void main()
{
string sTag;
object oUti;
resource rFileNames;
rFileNames = R"oracle_d.uti";
sTag = ResourceToTag(rFileNames); //gets all the tags from your file names
oUti = GetObjectByTag(sTag); //turns the tags into objects
int nIndex = GetLocalInt(oUti, sTag);
event ev = GetCurrentEvent();
int nEventType = GetEventType(ev);
// We will watch for every event type and if the one we need
// appears we will handle it as a special case. We will ignore the rest
// of the events
switch ( nEventType )
{
case EVENT_TYPE_EQUIP:
{
object oEquipper = GetEventCreator(ev); // The object equipping an item
int nInventorySlot = GetEventInteger(ev, 0); //
int bEquippedByPlayer = GetEventInteger(ev, 1); //
object oItem = GetEventObject(ev, nIndex); // The item being equipped
int nRace = GetCreatureRacialType(oEquipper);
if(nRace == 2)
SetAppearanceType(oEquipper,65010,TRUE);
else if(nRace == 3)
SetAppearanceType(oEquipper,65011,TRUE);
break;
}
case EVENT_TYPE_UNEQUIP:
{
object oItem = GetEventCreator(ev); // item being unequipped
int nInventorySlot = GetEventInteger(ev, 0); //
object oCreator = GetEventObject(ev, 0); //
int nRace = GetCreatureRacialType(oCreator);
if(nRace == 2)
SetAppearanceType(oCreator,2,TRUE);
else if(nRace == 3)
SetAppearanceType(oCreator,15,TRUE);
break;
}
}
}
#5
Posté 07 avril 2010 - 10:34
http://social.biowar...x.php/ECLog.ini
http://social.biowar...ategory:Logging
http://social.biowar...&_log_functions
http://dalexicon.net...gging_functions
Modifié par FollowTheGourd, 07 avril 2010 - 10:36 .
#6
Posté 08 avril 2010 - 02:16
#7
Posté 09 avril 2010 - 02:26
I also tried this with an effectmodifymovementrate rather than setappearance. This did try to apply the effect, but when you moved the screen went black and the game crashed here and there. So for some reason that effect is not well recieved by the game. I also tried an event scheme with Ability_DoRunSpellScript(blah, blah) for haste, that did absolutely nothing. So I feel limited to the apr thing, but that now is causing the head to change to some bald headed default.
#include "utility_h"
#include "wrappers_h"
#include "plt_oracle_plot"
#include "core_h"
void main()
{
object oPlayer = GetHero();
// If our plot flag is set to TRUE, that means we have already
// given the items to the player, there is no need to continue
// running this script.
if ( WR_GetPlotFlag( PLT_ORACLE_PLOT, ORACLE_CHECK_FLAG ) == TRUE )
return;
{
string[] sTags;
object[] oItems;
resource[] rFileNames;
// Gear
rFileNames[0] = R"oracle_a.uti";
rFileNames[1] = R"oracle_b.uti";
rFileNames[2] = R"oracle_c.uti";
rFileNames[3] = R"oracle_d.uti";
int x;
object oCreature = GetMainControlled();
//string sTag = "oracle_d";
//object oUti;
//gets all the tags from your file names
//oUti = GetObjectByTag(sTag); //turns the tags into objects
//int nIndex = GetLocalInt(oUti, sTag);
//effect eEffect = EffectModifyMovementSpeed(2.0);
for(x = 0; x
{
sTags[x] = ResourceToTag(rFileNames[x]); //gets all the tags from your file names
oItems[x] = GetObjectByTag(sTags[x]); //turns the tags into objects
//change the 1 to the amount of the item you want spawned
if(!IsObjectValid(oItems[x]))
{
UT_AddItemToInventory(rFileNames[x], 1, GetHero() , sTags[x] );
DisplayFloatyMessage( oPlayer , "Items added", 0 , 16777215 , 10.0 );
WR_SetPlotFlag( PLT_ORACLE_PLOT, ORACLE_CHECK_FLAG, TRUE );
}
//else if(IsObjectValid(oItems[3]))
//{
//DisplayFloatyMessage( oPlayer , "boots valid", 0 , 16777215 , 10.0 );
}
if(GetItemInEquipSlot(4) == oItems[3])
{
DisplayFloatyMessage(oCreature , "Item equipped is...", 0 , 16777215 , 10.0 );
//ApplyEffectOnObject(EFFECT_DURATION_TYPE_PERMANENT, eEffect, oItems[3]);
int nRace = GetCreatureRacialType(oCreature);
if(nRace == 2)
{
SetAppearanceType(oCreature,65010,FALSE);
}
else if(nRace == 3)
{
SetAppearanceType(oCreature,65011,FALSE);
}
DisplayFloatyMessage(oCreature , "effect applied", 0 , 16777215 , 10.0 );
}
else if(GetItemInEquipSlot(255) == oItems[3])
{
DisplayFloatyMessage(oCreature , "Item unequipped is...", 0 , 16777215 , 10.0 );
//RemoveEffect(oCreature, eEffect);
int nRace = GetCreatureRacialType(oCreature);
if(nRace == 2)
{
SetAppearanceType(oCreature,2,FALSE);
}
else if(nRace == 3)
{
SetAppearanceType(oCreature,15,FALSE);
}
DisplayFloatyMessage(oCreature , "effect removed", 0 , 16777215 , 10.0 );
}
}
}
// ---- SCRIPT ENDS HERE ----
Modifié par mutantspicy, 09 avril 2010 - 02:31 .
#8
Posté 09 avril 2010 - 02:33
It's not exactly what you had in mind (no extra attack speed), but maybe you could just give them the same effect as the haste spell.
Modifié par FollowTheGourd, 09 avril 2010 - 02:46 .
#9
Posté 09 avril 2010 - 02:34
#10
Posté 09 avril 2010 - 02:41
Here's the wiki entry I was talking about:
http://social.biowar...tem#Item_Script
The purpose of the item event script (if any) is not clear. Events involving items (acquire, lose, equip, unequip, etc…) are received by the event script for the creature or placeable owning the item, but are not received by the item script.
P.S., you reserved some M2DA ranges on the wiki but didn't say which ones they were for - just the numbers.
Modifié par FollowTheGourd, 09 avril 2010 - 02:41 .
#11
Posté 09 avril 2010 - 02:53
FollowTheGourd wrote...
I have a bad feeling about the face morph... just it seemed to be a blocker for people trying to set it when skipping chargen. EDIT: Then again, I'd have to check how the Fade scene lets you change and still return to your normal, morphed appearance without any problems.
It's not exactly what you had in mind (no extra attack speed), but maybe you could just give them the same effect as the haste spell.
Well I'm not opposed to using Haste effect on this, but I've tried that as well. With an event based command. Ability_DoRunSpellScript, that had no affect at all. So I'm not sure. There may be a way to do this with a get effect by ability ID type thing, which I ran across. So I may give that a shot. But man, this shouldn't be this friggin difficult. I mean if that effectmodifymovementrate variable actually worked and the so called event case based engine actually worked, this would have been a 10 min script. On working on a week and haven't gotten anywhere.
#12
Posté 09 avril 2010 - 03:12
FollowTheGourd wrote...
In your original script, which wasn't firing, what was it on: an item or a creature?
Here's the wiki entry I was talking about:
http://social.biowar...tem#Item_ScriptThe purpose of the item event script (if any) is not clear. Events involving items (acquire, lose, equip, unequip, etc…) are received by the event script for the creature or placeable owning the item, but are not received by the item script.
P.S., you reserved some M2DA ranges on the wiki but didn't say which ones they were for - just the numbers.
Honestly, I don't know what you mean by that. Its a simple add an item to your inventory mod. All I'm trying to do is add a set of boots that give you double movement rate. The original script for the boots with the events is set as the baseline script in the module properties, as the other scripts are ran by prcscr's they don't need be. I'm not creating a new creature, just armor. So I dunno what that means really in terms of your question. Does that mean this in an item event?
As far as, reserving m2da's, I wasn't sure what to do there. I personally think the way that page is set up is bunk. I mean you got people reserving 100,000 or 200,000 numbers because they are working on a playable mod. It should be broken down by resource type, items, spells, aprs, etc. I just wanted to reserve a small space for my custom item mods and I didn't see a relevent place to put it. Which I thought I pointed out, but maybe I didn't plainly enough.
#13
Posté 09 avril 2010 - 04:50
EDIT: There was some hope by a few people months back that the RegisterEventListener function might help avoid all that, but I haven't tried that myself and I haven't heard of it working for that since.
EDIT #2: It's apparently pretty broken, but I guess it might still work enough to let you know when to check if the PC or any follower in the party has the item equipped or not.
If it were just for a monster or NPC, you could probably have instead just created a renamed, custom creature_core script instead.
As far as the 2DA reservations go, I'll agree that some of them seem a little excessive, but there are a lot of numbers generally available (except for some 2DAs), so mainly it's just a way to know if somebody's already planning on using a range you were going to use.
My point was that a range without an associated 2DA file doesn't tell us anything...
Modifié par FollowTheGourd, 09 avril 2010 - 05:44 .
#14
Posté 09 avril 2010 - 02:56
But there is a small light at the end of the tunnel, as I figured out the issue with setappearance changin the head. I had to set the base to true. So it looks setappearance(oCreature,65010,TRUE) That keeps the head morphthe same as the chargen.
Modifié par mutantspicy, 09 avril 2010 - 02:57 .
#15
Posté 10 avril 2010 - 04:34
I created the following GDA's
engineevents_btsspd.gda
11, EVENT_TYPE_EQUIP, eventmanager
12, EVENT_TYPE_UNEQUIP, eventmanager
eventmanager_btsspd.gda
2000011, 11, EVENT_TYPE_EQUIP, 1 ------ I tried setting these to 2 and 0 also. Nada!
2000012, 12, EVENT_TYPE_UNEQUIP, 1
I copied the files
eventmanager.ncs
m2da_eventmanager.gda
to my addins\\\\core\\\\override\\\\toolsetexport folder.
After this wasn't getting it.
I also did a builder to builder load of the dadbdata file and tried again. Still not going.
I noticed in his mod description, he mentions the eventmanager needs to be embedded in the mod. I'm not sure what that means. I have the resources loaded in the toolset, but the eventmanager scripts are not under my oracle palette. The are listed by themselves. I dunno anyideas. What am I supposed to do next?
The script oracle_speed looks like
#include "wrappers_h"
#include "eventmanager_h"
void main()
{
string sTag;
object oUti;
sTag = "oracle_d"; //gets all the tags from your file names
oUti = GetObjectByTag(sTag); //turns the tags into objects
int nIndex = GetLocalInt(oUti, sTag);
event ev = GetCurrentEvent();
int nEventType = GetEventType(ev);
// We will watch for every event type and if the one we need
// appears we will handle it as a special case. We will ignore the rest
// of the events
switch ( nEventType )
{
case EVENT_TYPE_EQUIP:
{
object oEquipper = GetEventCreator(ev); // The object equipping an item
int nInventorySlot = GetEventInteger(ev, 0); // I assume the integer should match the inventoryslot I'm equipping to
int bEquippedByPlayer = GetEventInteger(ev, 1); //
object oItem = GetEventObject(ev, 0); // The item being equipped
int nRace = GetCreatureRacialType(oEquipper);
if(GetItemInEquipSlot(4) == oUti)
{
if(nRace == 2)
{
SetAppearanceType(oEquipper,65010,TRUE);
}
else if(nRace == 3)
{
SetAppearanceType(oEquipper,65011,TRUE);
}
}
break;
}
case EVENT_TYPE_UNEQUIP:
{
object oItem = GetEventCreator(ev); // item being unequipped
int nInventorySlot = GetEventInteger(ev, 0); //
object oCreator = GetEventObject(ev, 0); //
int nRace = GetCreatureRacialType(oCreator);
if(GetItemInEquipSlot(255) == oUti)
{
if(nRace == 2)
{
SetAppearanceType(oCreator,2,TRUE);
}
else if(nRace == 3)
{
SetAppearanceType(oCreator,15,TRUE);
}
}
break;
}
}
}
Modifié par mutantspicy, 10 avril 2010 - 04:36 .
#16
Posté 10 avril 2010 - 05:16
#17
Posté 10 avril 2010 - 12:28
It looks like those events were never implemented by the engine. I wasted several hours trying to figure out what I was doing wrong before I came across that post. (I'm trying to get a vfx to play on a character when they equip an item.)
The only possible alternative I see to both our problems is to write a new item property script that does what we want, then add that property to the item.
#18
Posté 10 avril 2010 - 01:18
I've read that post, and I just read it a again.
Where does it say Event_type_equip is unimplemented?
It hints that the item script is a bit broken, but realize I not writing an item script, I'm writing module script.
BTW. VFX is pretty easy unless its a custom VFX.
All you need to do is create a itemprps.gda, that calls the VFX you want.
Then add that propertie to your item.
You don't even need a script.
Modifié par mutantspicy, 10 avril 2010 - 01:35 .
#19
Posté 10 avril 2010 - 02:23
I think in order to get a module to handle those events, you'll need to register event listeners tied to each creature that could possibly use that item. That's not the best way to go. It will probably be more efficient to make a custom spell effect and tie it to an item property.
As for my VFX issue, I think I'll have to go the spell effect + item property route too, since it's a set of custom VFX, and the one that gets applied is based on several creature and item variables.
#20
Posté 10 avril 2010 - 02:49
getmaincontrolled() since the only creature who equip the item would have to be controlled. That said, thats where I'm have the trouble I'm not sure how you go about registering a listener.
Though you maybe right, creating an effect that changes the appearance maybe alot more solid and compatible. Though thats sort of back to the drawing board and I have to rethink all my GDA's, etc. The other issue that held me back from trying that is effects.gda is pretty much undocumented in the wiki so I'm not sure what all the columns refer to.
#21
Posté 10 avril 2010 - 03:27
#22
Posté 10 avril 2010 - 04:51
I created an itemprps id = 2000004 which call effect 2000005
Then created an effect gda with Id 2000005 label EFFECT_TYPE_SPEED.
Then add this script to my resources in the module. Its not tied to the item or module or any creatures its just in the resources.
const int EFFECT_TYPE_SPEED = 2000005;
void main()
{
object oCreature = GetMainControlled();
int nRace = GetCreatureRacialType(oCreature);
effect eSpeed;
{
if(nRace == 2)
{
SetAppearanceType(oCreature,65010,TRUE);
}
else if(nRace == 3)
{
SetAppearanceType(oCreature,65011,TRUE);
}
eSpeed = Effect(EFFECT_TYPE_SPEED);
}
}
I still got nothing. It did say after compiling, unable to get script resources. Even though compile was successful. So I wonder if there is an #include I need to add to set the const variable. Also I'm not sure if this effect script gets ran. Sure its tied to the item, through the GDA's. But what makes the script run?
Modifié par mutantspicy, 10 avril 2010 - 05:00 .
#23
Posté 11 avril 2010 - 08:14
I managed to hook the module event handler onto each member of the player party pool, but when you unequip or equip items from them, they aren't sending the equip/unequip events to the module. They send EVENT_TYPE_LISTENER instead. It's too late for me tonight to break down the listener event contents and figure out what data it contains, but I should have more information tomorrow.
The code I used to hook the party is listed below:
#include "log_h"
#include "utility_h"
#include "wrappers_h"
#include "events_h"
void main()
{
event ev = GetCurrentEvent();
int nEventType = GetEventType(ev);
string sDebug;
object oPC = GetHero();
object [] oPartyList = GetPartyPoolList();
int nEventHandled = FALSE;
PrintToLog("Module Handler :event " + IntToString(nEventType)+" from " + GetName(GetEventCreator(ev)));
switch(nEventType)
{
case EVENT_TYPE_MODULE_START:
case EVENT_TYPE_MODULE_LOAD:
{
PrintToLog("event mod start/load");
//assign listeners to each member of the party
int i;
for (i = 0; i < GetArraySize(oPartyList); i++)
{
PrintToLog("Register listener " + GetName(oPartyList[i]));
RegisterEventListener(oPartyList[i], OBJECT_SELF, EVENT_TYPE_EQUIP);
RegisterEventListener(oPartyList[i], OBJECT_SELF, EVENT_TYPE_UNEQUIP);
}
break;
}
//other event cases
}
if (!nEventHandled)
{
HandleEvent(ev);
}
}
If you activate log script recording, this code will write to DragonAge_1.log everytime an event passes through the module handler.
#24
Posté 11 avril 2010 - 02:10
#25
Posté 12 avril 2010 - 01:51
It turns out that player/party event calls are shut off by default. You can have your module turn player events on and assign a custom player event script to the party when it starts/loads up.
first script:
//module/addin event handler
#include "log_h"
#include "utility_h"
#include "wrappers_h"
#include "events_h"
void main()
{
event ev = GetCurrentEvent();
int nEventType = GetEventType(ev);
string sDebug;
object [] oPartyList = GetPartyPoolList();
int nEventHandled = FALSE;
PrintToLog("my module handler :event "+IntToString(nEventType)+" from "+GetName(GetEventCreator(ev)));
switch(nEventType)
{
case EVENT_TYPE_MODULE_START:
case EVENT_TYPE_MODULE_LOAD:
{
PrintToLog("event mod start/load");
//assign custom event handler to each member of the party
int i;
for (i = 0; i < GetArraySize(oPartyList); i++)
{
PrintToLog("assign event handler to " + GetName(oPartyList[i]));
EnablevEvent(oPartyList[i],TRUE,EVENT_TYPE_EQUIP);
EnablevEvent(oPartyList[i],TRUE,EVENT_TYPE_UNEQUIP);
SetEventScript(oPartyList[i],R"my_player_event_handler.ncs");
}
break;
}
}
if (!nEventHandled)
{
HandleEvent(ev);
}
}
second script:
//player event handler
#include "log_h"
#include "utility_h"
#include "wrappers_h"
#include "events_h"
void main()
{
event ev = GetCurrentEvent();
int nEventType = GetEventType(ev);
string sDebug;
object oUser = OBJECT_SELF;
switch(nEventType)
{
case EVENT_TYPE_EQUIP:
{
object oItem = GetEventObject(ev,0);
PrintToLog("event equip: "+GetName(oUser)+" - "+GetName(oItem));
//do stuff here
break;
}
case EVENT_TYPE_UNEQUIP:
{
object oItem = GetEventObject(ev,0);
PrintToLog("event unequip: "+GetName(oUser)+" - "+GetName(oItem));
//do stuff here
break;
}
}
//always let the default event handlers process the rest of the event otherwise things will break
HandleEvent(ev, RESOURCE_SCRIPT_PLAYER_CORE);
}
Hopefully, that takes one of the major obstacles out of the way of getting your stuff to work
Modifié par barrelofmonkeyzz, 12 avril 2010 - 01:54 .





Retour en haut







