Aller au contenu

Photo

What script does the spell casting GUI call?


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

#1
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
I am working on altering the targeting of spells to remove the standard restrictions imposed by the coding of the spells.  For example, one of the things I want to do is to allow a player to cast a harmful spell on a neutral character, something that the game does not allow unless altered. 

I have a script which will do this, and now I need to make the GUIs for spellcasting call the script.  Does anyone know where this is located, or if it is hard coded?

#2
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
I've been digging through the game and I can't find anything in the UI folder that seems like it is sending callback functions to the server from the GUIs that control spellcasting. I looked at the XML for the quickcast menu and spells known menu and there don't seem to be any callback functions for on left click events. I wonder if the spell selection is controlled by other XML files elsewhere.

#3
Orion7486

Orion7486
  • Members
  • 161 messages
Two thoughts. Have you checked the options in the campaign plugin screen? I think there is something there you can set.

Also, this could be something that was set within the specific spell script. You could look into changing this specific spell script to allow unrestricted targeting, or if this is something you want to do with many spells, try looking into spellhooking. This allows changes to all spells within one script.

Hope any of this helps.

#4
_Knightmare_

_Knightmare_
  • Members
  • 643 messages
Not sure if this is what you are looking for or if it will be of any help (I don't do much with spells), but the spells.2da file has column for:
 
- "Target Type" (which I think is the type of objects you can cast the spell at) - so change the entry of the spell your looking to edit (or add new) to one like a spell that can be cast at neutrals.

- "Targeting UI" which sounds like the targeting GUI used. What those numbers mean, I'm not sure.
- "Impact Script" says which script if fired off for that spell. You can then find/look at that script in the toolset by doing a File -> Open Conversation/Script and entering the script name.

Also, your module/server PvP settings might have something to do with it, might need it set to allow attacking of neutrals (which is actually a Campaign option, not a module option).

#5
Guest_Chaos Wielder_*

Guest_Chaos Wielder_*
  • Guests
I believe they're right on: check the campaign settings via the plugin tab. There's quite a few interesting options up there.

#6
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
Thanks for the replies and the help. I have tried changing several settings in the campaign menu to no avail. I will go back and see if I missed any settings that I can change. This does give me an idea to try to mess with the PVP settings and see if that changes anything.



KM, you are right that changing the .2DA files will work. One challenge with this approach is that there is no constant that allows you to target anything, as far as I know. You have to choosh either hostile, or caster, or friendly... etc... there is no category that works for all of them. I have heard of a technique whereby you can make a spell behave like the protection from alignment spell which has options when you choose to cast the spell, but I also want my campaign to be compatible with Kaedrin's, so I am trying to avoid messing with .2DA files.



The system I have can accomplish the task if I can just find the code that handles what happens when you left click on the quick cast GUI. I looked at the .xml code and I can't find any onleftclick events for the buttons in the GUI. The xml for the hotbar is the same way. I can't figure out how the engine interfaces with the quickcast and hotbar GUI for handling input.


#7
M. Rieder

M. Rieder
  • Members
  • 2 530 messages

_Knightmare_ wrote...

Not sure if this is what you are looking for or if it will be of any help (I don't do much with spells), but the spells.2da file has column for:
 
- "Target Type" (which I think is the type of objects you can cast the spell at) - so change the entry of the spell your looking to edit (or add new) to one like a spell that can be cast at neutrals.

- "Targeting UI" which sounds like the targeting GUI used. What those numbers mean, I'm not sure.
- "Impact Script" says which script if fired off for that spell. You can then find/look at that script in the toolset by doing a File -> Open Conversation/Script and entering the script name.

Also, your module/server PvP settings might have something to do with it, might need it set to allow attacking of neutrals (which is actually a Campaign option, not a module option).



You were right.  This worked for my purposes. I modified the hexidecimal value for the the "targettype" field and it worked.  Thanks.  I'm going to monkey with these and see how far I can take this.

#8
_Knightmare_

_Knightmare_
  • Members
  • 643 messages
NP, please let us know what you discover. :)

#9
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
I discovered that I can alter what types of targets can be selected very easily. Lets take mirror image as an example. Normally it can only be applied to items, self, and placeables. By changing the TargetType, you can also allow creatures to be targeted. Now, you can cast mirror image on companions, summoned creatures, the town drunk (just to confuse him more!) etc...



I found out that there is field called hostile which is either a 1 or a 0 for all spells. This is the problem. A spell has to be either helpful or harmful, it can't be both (or so it seems). So a simple .2DA edit cannot fix this part. You would have to make a sub spell. I just realized, though, since my campaign is just for magic users and does not support warlocks (not much does support warlocks by the way. Consider combat, for example), I decided that if I do need to make extra spells to allow certain spells to be cast on enemies or friendlies, I can just hijack the 2DA lines that are used for warlok incantations. I suppose I could do druids as well, or clerics, but I would like to leave them open as someone may like to try a druid or cleric/ magic user.



Actually, maybe I'll just take the 2DAs for epic warlock stuff since if someone does dual class, they won't make it to epic levels (not that they will hit epic in this campaign, but maybe in the future, I want to keep my options open.)

#10
MasterChanger

MasterChanger
  • Members
  • 686 messages
Have you considered using the "cursor" approach that 0100010 talked about, using the Spellhook (or a script called by it) to call the GUI?

Just a thought, not a fully-formed approach.

#11
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
I did. In fact, I spent my last 8 hours or so of toolset time working on this approach. It works very well, but I couldn't figure out how to seamlessly integrate it into the spellcasting GUI system. What I wanted to do was find the code that handles the event when a player left clicks a spell in the quickcast, then put cursor approach in there. Unfortunately, the xml documents in UI cannot (as far as I could tell) be easily modified to perform this, and Pain tells me that this is an engine level function and I would probably have to completely redo the quickspell GUI. I just don't have the time resources to do this, so I am going to have to do work-arounds.



There may be an easier way, but I don't know enough to find it. If you ever find a way to break into the spellcasting UI, please let me know. It would be very helpful.




#12
MasterChanger

MasterChanger
  • Members
  • 686 messages
Yeah, I know. You won't be able to get between the click on the quick-cast and the targetting UI it brings up based on target-type. That isn't what I meant.

The impact script in question will call GetSpellTargetObject and/or GetSpellTargetLocation, which looks at what you clicked on. What if you did away with that? What if you changed the spell in the 2da to a target-self only spell, then did the targetting work through the impact script or spell-hook? Then you store the target location or object as a local variable.

If you don't want to do this (it might be more work, though that probably depends on how many spells you'd be updating) I'll stop pushing. I just wanted to talk about the options that might be available.

#13
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
Oh, hey, now I get it. I could make the spell like a wildshape or the ability "elephant's hide". That way, as soon as the player clicks on the icon, the script fires and pulls up the new targeting cursor. That way it would be seamless and the player wouldn't be able to tell the difference!

Hey, that might just work! The only problem is if there is something hardcoded into the engine that signals the special spells like wildshape, etc that they don't need a targeting cursor.

I definitely want to keep trying to get this to work.  If I can open up the targeting for spells, then my campaign will have lots more options. 

Modifié par M. Rieder, 26 décembre 2010 - 05:05 .


#14
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
Holy Crap! It works. If you go into spells.2da and change the field "targetype" to 0x01, then as soon as you click on the spell icon, it automatically casts the spell on the caster without showing a cursor!

I only tried it with the 9th level wizard spell "shapechange" so far, but it looks very promising. Now I just have to enter the code to get the new targeting cursor up and we should be in buisness!

Thanks for the idea and encouragement, MasterChanger, I had pretty much given up hope. I think this may yet come together! Not tonight though.

Cheers!

Modifié par M. Rieder, 26 décembre 2010 - 05:22 .


#15
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
I just put in the code to create the targeting cursor in the script for charm person and was able to create a targeting cursor that would target both friendly and neutral creatures. It worked seamlessly. As soon as I clicked on the GUI button for charm person the correct cursor appeared. Now I just have to hook in the code for the spell charm person. I think this is going to work.

There is one issue. The effect for spellcasting fires before the cursor appears. This is because the effect for spellcasting is called by the GUI (I assume). This can probably be fixed by removing the .sef from the 2DA file for the spell in question, decreasing the casting time from 1000 (standard for all spells but one or two) to 0, then adding the .sef and casting delay back in with the script after the cursor has appeared.

Modifié par M. Rieder, 26 décembre 2010 - 05:53 .


#16
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
I did it. I just made it where I can cast the spell scare on neutrals or enemies. I just finished writing up a tutorial. I'm going to have someone go over it before I post it to make sure it makes sense.



Making this happen is an involved process, but it works and can greatly increase the depth of magic use in a campaign.


#17
kevL

kevL
  • Members
  • 4 070 messages
sounds Good, MR. can't wait to get my eyes on it

anecdote : first time playing OC, I'm not an 'attack guards' kinda guy. But getting frustrated with the railroading etc. Finally some NPC p.o's me enough, think "now, How did I do this in NWN?" oh yeah, right click->Attack! ...

So, if this'll let the PC cast MagMiss from a safe distance to initiate combat, great - if it doesn't, still sounds Good

#18
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
Theoretically, this could be made into a mod that could make all the spells in the game available for casting on both hostile and non-hostile. What I have done is simply work out the mechanics of how it can be done based on the work of other scripters. This system can be used to do an unlimited number of things through scripting. The challenge is really the amount of scripting that will be required for each spell changed.



I plan to use it in my next module, The Wizard's Apprentice II to allow the player to use spells in a wider variety of situations other than just to buff allies and slay enemies.




#19
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
How about just using radial spells, that way it does not pause the spell after you cast it while the game waits for you to click on something -- i can see this being a way to manipulate how the game works very easily. ( take a look at dispel, the way kaedrin set that up to allow hostile and friendly, that way you can queue it up as either hostile or friendly )



Yes i changed quite a few spells to allow targetless self casting, only issue is you can't create scrolls as easily.

#20
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
Radial spells is better, but I am a little concerned with compatibility with Kaedrin's. I guess that if I just modify a few spells, I could merge it with Kadrin's spells.2da. Is that necessary?

#21
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
Here's a link to a file with a tutorial and demo of what I have so far. It is rudimentary and not perfect, but is does work and it is interesting.



http://www.mediafire...hdwxb80xiyxf9db

#22
MasterChanger

MasterChanger
  • Members
  • 686 messages
OK, I tried it and it does seem pretty interesting. I've run into two issues, one being just a limitation and the other being some sort of bug.

The limitation is that you cannot use the setting that automatically runs the action on your currently selected target, or you run into weird behavior. When I play a spell-caster and I use non-AoE spells, I prefer to use this setting because then you make sure of your target before you cast. Unfortunately, it won't work with those approach.

The bug I've run into is that it seems that at certain times the effect of the spell is applied to the caster as well as to the target. At first I thought that it was because you left the GetSpellTargetLocation call in, and the GetFirstObjectInShape loop*. But I commented that out and still, when I cast at any target my character has to save or be scared as well.

I also think it's interesting that you moved the effect on a neutral creature to the on_spell_cast event rather than the spell script itself. Not that there's anything wrong with this, but it might be best to see all the effects of the spell in one spot IMO.

* The Scare spell is only sort-of an AoE spell. It can effect up to (nCasterLvl / 3) + 1 targets, but does specifically start with the target you selected. Kinda weird that way. It might be better to use GetLocation(oTarget) for the location check, based on the target retrieved from the GUI.

Modifié par MasterChanger, 27 décembre 2010 - 04:19 .


#23
MasterChanger

MasterChanger
  • Members
  • 686 messages
Actually, inserting the line
location lTarget = GetLocation(OBJECT_SELF);
...and then...
lTarget = GetLocation(oTarget);
...after the...
if (GetIsObjectValid(oTarget))
...check seems to fix the cast-on-self problem. It still affects the caster if you select yourself as the target, and I think that's because
(spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, OBJECT_SELF)
...is wonky at Hardcore difficulty and above.

At any rate, as a proof-of-concept, it does seem to work!

#24
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages
Hi Matt,

Thanks for keeping me in the loop with respect to this. I have read your tutorial and can now understand the approach you are using. The main problem I see, is that this is still a *lot* of work if you want to change all spells to work in this way. It's probably best for the odd spell ... or for somebody who has a lot of patience. ;)

Frustratingly (for me), I have already started going through (and altered) every spell code, not once, but twice for some of my own alterations. I don't think I have the heart to go through a third time (for all at least).

In the back of my mind, I still wonder if there is another way to make this simpler (via spell hooking as well). (Probably just wishful thinking.) As an alternative (and my favourite course of action to date unless I find a better way), I am also considering writing a simple targeting GUI to allow a player to tell the game if they want to consider/turn an NPC hostile from afar. Once hostile, the targeting issue disappears. One could even add an option to change all associated with the targeted NPC hostile, or keep if singular if possible (as others may automatically become hostile anyway).

Thanks again for this ... and keep me updated. I will do the same if I should ever find another solution.

Lance.

Modifié par Lance Botelle, 27 décembre 2010 - 02:33 .


#25
BartjeD

BartjeD
  • Members
  • 249 messages
Perhaps you can turn someone temporarily hostile to the spellcaster in the spellhook? Thereby you avoid the code and factions I think.



You can turn them permanently hostile by seeing if it's a hostile spell (from the 2da column) and then making then faction hostile.



So you'd have if(NonHostileSpell) ---> {Make temporarily caster's enemy}

else if(HostileSpell) ---> {Make permanent hostile...}