Page 1 of 2

My usecode questions

Posted: Tue Nov 24, 2009 2:50 pm
by Crowley
I thought I'd make a separate thread for asking about ways to figure out my usecode ambitions, or even if they are possible.

First up is the plan to make a Chaos Sword that acts similar to how it did in Ultima V. At the base is the charmed condition, which seems to accomplish neatly the effect of making a party member attack the rest of the group. However, I was thinking of mixing it up a little. Would it be possible to have the game run an additional check every time combat mode is entered, and only then set the charmed status on the person wielding the sword? That I think would be a more effective and subtle solution that simply make the charmed state last indefinitely as long as someone wields the sword.

Re: My usecode questions

Posted: Tue Nov 24, 2009 4:10 pm
by Crowley
Hmm, while I do not see it mentioned in the usecode itself anywhere, would it be possible to make a script that monitors the toggle_combat function?

Re: My usecode questions

Posted: Fri Nov 27, 2009 8:00 pm
by Crowley
No comments? Well, now I have a specific sample of usecode and wonderment over why it doesn't work. I have a Skull Key which is supposed to unlock magically locked doors, but it doesn't. Furthermore, the game only exits the targeting mode after I click twice, and I can only get out the second message about not using the key on a door.

void SkullKey shape#(0x400) ()
{
if (event == DOUBLECLICK)
{ UI_close_gumps();
UI_click_on_item();
var target = UI_click_on_item();
var lock_shapes = [SHAPE_DOOR_HORIZONTAL, SHAPE_DOOR_VERTICAL, SHAPE_DOOR2_HORIZONTAL, SHAPE_DOOR2_VERTICAL, SHAPE_CHEST, SHAPE_LOCKED_CHEST];
var target_shape = target->get_item_shape();
if (target_shape in lock_shapes)
{
var target_frame = target->get_item_frame();
if (((target_frame + 1) % 4) == 0)
{
var unlock_frame = (target_frame - 3);
set_item_frame(target, unlock_frame);
return;
}
else
{
avatarBark("@The key doesn't fit.@");
return;
}
}
else
{
randomPartyBark("@There is no lock on that.@");
return;
}
}
}

Re: My usecode questions

Posted: Fri Nov 27, 2009 11:29 pm
by marzo
Here is the cleaned up, formatted and corrected code:

Code: Select all

void SkullKey shape#(0x400) ()
{
	if (event == DOUBLECLICK)
	{
		UI_close_gumps();
		// This is only needed once:
		// UI_click_on_item();
		var target = UI_click_on_item();
		// This is the case where nothing is clicked:
		if (!target)
		{
			randomPartyBark("@That is the ground, avatar!@");
			return;
		}
		var lock_shapes = [SHAPE_DOOR_HORIZONTAL, SHAPE_DOOR_VERTICAL, SHAPE_DOOR2_HORIZONTAL, SHAPE_DOOR2_VERTICAL, SHAPE_CHEST, SHAPE_LOCKED_CHEST];
		var target_shape = target->get_item_shape();
		if (target_shape in lock_shapes)
		{
			var target_frame = target->get_item_frame();
			if (((target_frame + 1) % 4) == 0)
			{
				var unlock_frame = (target_frame - 3);
				// This is wrong:
				// set_item_frame(target, unlock_frame);
				// It is equivalent to
				// item->set_item_frame(target);
				// This is the correct form:
				target->set_item_frame(unlock_frame);
				// Also correct would be:
				// UI_set_item_frame(target, unlock_frame);
				return;
			}
			else
			{
				avatarBark("@The key doesn't fit.@");
				return;
			}
		}
		else
		{
			randomPartyBark("@There is no lock on that.@");
			return;
		}
	}
}

Re: My usecode questions

Posted: Fri Nov 27, 2009 11:53 pm
by Crowley
Thank you. That helps me figure things out. There is one oddity left. Using the key on a non-magically locked door or chest with this code doesn't cause the line about key not fitting to show up, or any line at all. However, there was no problem if I simply switch it to randomPartyBark.

Re: My usecode questions

Posted: Sun Dec 06, 2009 4:46 pm
by Crowley
All right, next up is the code for the feeding function of my Horn of Plenty. At first it seems to work fine, but something about it breaks the feeding slightly. Afterwards, trying to feed normal food to someone who is above the "hunger threshold" (food level above 24, I believe) still raises the NPC's food level, though it does not consume the food item.

Code: Select all

void HornOfPlenty shape#(0x402) ()
{
	if (event == DOUBLECLICK)
	{	
		var target = UI_click_on_item();
		var party = UI_get_party_list();
		if (!target)
		{
			UI_flash_mouse(1);
			return;
		}
		else if (!(target in party))
		{
			UI_flash_mouse(1);
			return;
		}
		else
		{
			var targetfood = (target->get_npc_prop(9));
			if (targetfood > 24)
			{
				target->item_say("@No, thank thee.@");
				return;
			}
			else
			{
				target->set_npc_prop(9, (targetfood + 31));
				target->item_say("@Ahh, I am full now.@");
				return;
			}
		}
	}
}

Re: My usecode questions

Posted: Sun Dec 06, 2009 5:18 pm
by marzo
You are overfeeding them enourmously with this line:

Code: Select all

target->set_npc_prop(9, (targetfood + 31));
What you want is this:

Code: Select all

target->set_npc_prop(9, (31-targetfood));
Your version increases the food level to targetfood+targetfood+31, while the version I gave raises it to 31.

Re: My usecode questions

Posted: Sun Dec 06, 2009 5:46 pm
by Crowley
Oh yes, I didn't think of doing it that way. It seems that the feeding glitch doesn't have anything to do with my code, but is exists in the original as well (at least when running an unmodded game in Exult). It does seem to be fixed in the Keyring Mod, which I used as comparison and it made me think I had broken something.

Now onwards to try and figure out the infinite reagents behaviour and Chaos Sword. Sadly it seems that toggle_combat cannot be used in usecode.

Re: My usecode questions

Posted: Sun Dec 06, 2009 7:22 pm
by Malignant Manor
Infinite reagents is currently hard-coded in the engine.

Re: My usecode questions

Posted: Sun Dec 06, 2009 7:55 pm
by Crowley
I completely forgot that is already in the game in the form of Wizard Mode in the cheats. I guess the question is then, is infinite reagents hardcoded into the game in a way that custom usecode could be used to toggle it on and off without also enabling the full spellbook and infinite mana?

Re: My usecode questions

Posted: Sun Dec 06, 2009 8:06 pm
by Crowley
Alternatively, perhaps the effect could be achieved by making an unopenable container which has 99 of each reagent, and usecode which refills them?

Re: My usecode questions

Posted: Sun Dec 06, 2009 8:10 pm
by Malignant Manor
It's set to shape 296, frame 3 in SI being worn on a finger spot. It's not in the usecode at all. You'd have to make a text based spell book. It's on Marzo's ever expanding to do list. It's planned to be a frame power setting. It's pretty easy to setup but Marzo planned to dehardcode the entire spellbook as much as easily feasible.

Re: My usecode questions

Posted: Sun Dec 06, 2009 8:20 pm
by Malignant Manor
A container like that would be 8+ pounds. I'm not sure if the container can refill overtime while in a container but double clicking it would be an easy way to refill it since it wouldn't need refilled very often if at all. If readied it could likely be easily updated over time.

Re: My usecode questions

Posted: Sun Dec 06, 2009 8:28 pm
by Crowley
Good thing then that I already intended the Horn of Plenty to be big and heavy. I'll look into what I could do with usecode. Thanks for all the information.

Re: My usecode questions

Posted: Sun Dec 06, 2009 10:15 pm
by Malignant Manor
One problem I just thought of is how Marzo fixed locked containers to make the contents inaccessible. The spellbook seems to be able to access and detect the reagents (a bug), but I'm not sure that usecode will be able to detect the contents properly to update it. I think the find intrinsics might not return the contents inside a container.

Re: My usecode questions

Posted: Mon Dec 07, 2009 3:12 am
by Wizardry Dragon
Just use the usecode container and use a script to put reagents in it. The game should search it too.

Wizardry Dragon

Re: My usecode questions

Posted: Mon Dec 07, 2009 5:18 am
by Crowley
I was hoping that the custom usecode for double-clicking would override opening the gump, but that was not meant to be. Perhaps I shall simply wait for Marzo's new code for spells, and hopefully he has made progress in implementing the anti-magic effect as well.

Re: My usecode questions

Posted: Mon Dec 07, 2009 6:01 am
by Wizardry Dragon
You can freely peruse his spells code in the TFL repository :)

Wizardry Dragon

Re: My usecode questions

Posted: Mon Dec 07, 2009 6:42 am
by Crowley
Ooh, what lovely progress he has made. It would be very nice to eventually have hostile (human) spellcasters who actually do say the incantations and have reagents they have to use. There does not seem to be anything about the consumption of reagents in Marzo's code yet, though.

Re: My usecode questions

Posted: Mon Dec 07, 2009 6:46 am
by Wizardry Dragon
If I recall correctly, reagents are considered only by the game engine. I'm entirely unsure how difficult it would be to modify the engine to allow usecode to override this behaviour. It certainly wouldn't be hard to destroy the appropriate items in the NPC's inventory.

And TFL already has hostile spellcasters, and not just with the "spell weapon" hack that U7 used. I really need to get my real internet to work enough to commit - Im posting from my iPhone >.>

Wizardry Dragon

Re: My usecode questions

Posted: Mon Dec 07, 2009 6:56 am
by Crowley
Interesting. What about the spellcasting creatures which (at least in my opinion) should skip things like incantations and reagent consumption, like dragons, gazers and reapers?

Re: My usecode questions

Posted: Mon Dec 07, 2009 7:01 am
by Wizardry Dragon
My spellcasting NPCs - true spellcasting that is - are exceptions. I have not rewritten the base NPC code or taken away the spellcasting "items" from existing NPCs - that would be an awful lot of work for very little "payout".

Instead I simply wrote usecode based on the party companion usecode, to allow my new NPCs to also cast spells intelligently with a spellcasting item.

Wizardry Dragon

Re: My usecode questions

Posted: Mon Dec 07, 2009 7:10 am
by Crowley
I can understand that. Personally I might be crazy enough to do the grunt work of going through every NPC, spawn egg and pre-existing monster in the game and switch things around accordingly.

Re: My usecode questions

Posted: Mon Dec 07, 2009 7:11 am
by Crowley
And I guess you meant to say "cast spells intelligently without a spellcasting item"?

Re: My usecode questions

Posted: Mon Dec 07, 2009 7:36 am
by Wizardry Dragon
No, actually, in that case I meant spellcasting item as in the context of the specific item that is used as a spellbook item for NPCs, the same shape incidentally as Laurianna's spellbook - it just uses different quality frames for different items.

I do apologise for the mixed terminology though, I'm here in the late night/early morning out of insomnia, and probably aren't making much sense :)

Wizardry Dragon

Re: My usecode questions

Posted: Mon Dec 07, 2009 12:46 pm
by Crowley
Gotcha. I guess I'll be waiting for that projected February release then.

Re: My usecode questions

Posted: Mon Dec 07, 2009 12:49 pm
by marzo
A few notes: the spellcasting code in Keyring/TFL has a 'spellbook' of sorts which allows NPCs to cast spells. It checks for reagents and mana if the NPC is in party or waiting around; but assumes that the NPC can rest and gather reagents (i.e., cast infinitely many spells) if not in party.

Re: the changes I am making: when they are finished (which won't be for some time, sadly), you will be able to make custom spellbooks, drawn from a pool of 16 spells per circle. Each spellbook can have from 1 to 16 spells per circle, and may come in 'minor caster' (up to circle 4) and 'caster' varieties (all circles); each can be flagged as not requiring mana nor reagents or as being exclusive to the avatar.

Also, there will be items you can flag as being the "ring" of reagents -- they must be equipped, however. I had thought about allowing specially customized reagents which would actually fit perfectly for that cornucopia (i.e., a shape could count as being several reagents), but decided that it was too much work for too little gain.

Finally, there will be a way to force a container to run usecode instead of opening a gump. There were some containers that did this (trapped chests, IIRC), so I decided to allow them for other purposes too.

Re: My usecode questions

Posted: Mon Dec 07, 2009 2:02 pm
by Crowley
Fair enough, I can live without enemies using reagents. I am mainly interested in the possibilities of implementing an anti-magic effect which affects enemies and an infinite reagents item.

Re: My usecode questions

Posted: Tue Dec 08, 2009 2:44 pm
by Crowley
I just had a thought: with new code for spellcasting, couldn't I tie refilling the cornucopia to casting every spell? Preferably to the end after checking the number of reagents and consuming them is done. Now, if only showing the infinity symbol in the spellbook could be separated from wearing a reagent supply, then I could vary the weight of the cornucopia.

Re: My usecode questions

Posted: Tue Dec 08, 2009 3:13 pm
by Wizardry Dragon
You'd have to rewrite the usecode handler for spellcasting, but it is possible.

Wizardry dragon

Re: My usecode questions

Posted: Tue Dec 08, 2009 4:10 pm
by Crowley
Are you referring to the refilling, infinity symbol display, or both?

Re: My usecode questions

Posted: Tue Dec 08, 2009 5:07 pm
by Wizardry Dragon
Specifically, to have the cornocopia refill when you cast a spell, the best approach would be to take marzos implementations of the spells, and add a call to a function that does whatever you want the spell effe t to be (in this case the refilling effect)

In regards to the infinity symbol you could just make a new font and use that one - on of the things I requested Marzo to add to the ucc language was the ability to use different fonts with ui_dispay_gump. If memory serves he did indeed add that functionality.

Wizardry dragon

Re: My usecode questions

Posted: Tue Dec 08, 2009 5:11 pm
by Crowley
Regarding spells and refilling, that is precisely what I had in mind.

Re: My usecode questions

Posted: Tue Dec 08, 2009 5:11 pm
by marzo
Since -- for NPCs -- the spellcasting code from Keyring/TFL does its own reagent management, you could easily add a check for the cornucopia and don't use reagents. For the avatar, though, it would be trickier.

Re: infinity symbol: you will be able to set one for spellbooks when I finally commit, but it will require a font change. Also, it can't currently be done in BG.

Re: My usecode questions

Posted: Tue Dec 08, 2009 5:29 pm
by Wizardry Dragon
Haven't I been bothering you for the better part of a year to add that to bg? :p

Wizardry dragon

Re: My usecode questions

Posted: Tue Dec 08, 2009 7:38 pm
by Crowley
Now for some of my other questions: Is it possible to trigger a script to run when you enter combat mode or for when you exit it? For example, make a character who has never been in combat before, and the first time it happens he or she freezes, and then vomits once you end combat.

Re: My usecode questions

Posted: Wed Dec 09, 2009 3:59 pm
by Wizardry Dragon
There is a usecode function called when you enter combat though I can't recall what number. Just rewrite its functionality and include that.

Wizardry dragon

Re: My usecode questions

Posted: Wed Dec 09, 2009 6:48 pm
by Crowley
I guess it would be something like get current schedule, if not in_combat, set schedule to in_combat, otherwise set schedule to follow_avatar?

Re: My usecode questions

Posted: Wed Dec 09, 2009 7:00 pm
by marzo
Actually, the only way to detect what you want would be for a script block to "permanently" run periodically checking for combat; there is no other way to trigger an event on a schedule change.

Re: My usecode questions

Posted: Wed Dec 09, 2009 7:21 pm
by Crowley
All right.

One more thing regarding the cornucopia came to mind. If I go with the "unopenable replenishing container" method, how might I ensure that if the Avatar is carrying both the cornucopia and regular reagents, only reagents from the former are used?

Re: My usecode questions

Posted: Wed Dec 09, 2009 10:42 pm
by Wizardry Dragon
I remember bothering Jeff for an "event" functionality to be incorporated into Exult waaay back when we first got UCC, to trigger usecode off it, but the project had more pressing issue bac then. I'm not sure it would be too difficult to add, just add usecode functions that the Exult engine calls in addition to its normal calls - functions which mod authors could then override.

Wizardry dragon

Re: My usecode questions

Posted: Wed Dec 09, 2009 10:45 pm
by Crowley
It would help enormously if I could just set the code to run when toggle_combat is called.

Re: My usecode questions

Posted: Thu Dec 10, 2009 3:08 pm
by Wizardry Dragon
I'll see if I can't patch that functionality in though it would be unofficial since Im not a member if the exult team :)

Wizardry dragon

Re: My usecode questions

Posted: Fri Dec 11, 2009 12:35 am
by marzo
If you do, please submit it to the patch tracker for consideration.

Re: My usecode questions

Posted: Thu Apr 29, 2010 5:37 pm
by Crowley
This isn't strictly usecode-related, but I thought I'd ask it here. I remember some discussion about including the map of Britannia in Serpent Isle and it was mentioned that you couldn't add a different map sprite to be displayed when using it. So, is the use of "slots" in sprites.vga hardcoded so that you can't just add a completely new sprite to be displayed when using something?

Re: My usecode questions

Posted: Thu Apr 29, 2010 10:46 pm
by Malignant Manor
You can easily include different maps.

Both Games:
UI_display_map_ex(int mapshp, bool show_loc)

SI only:
UI_si_display_map(int num)

Re: My usecode questions

Posted: Thu Apr 29, 2010 10:56 pm
by Malignant Manor
Those maps still use the same shape though, but it's not like you can't have a huge amount of frames.

Sprite display can use different shapes. Only some things called by the engine are hardcoded.


** All Games **

teleport", 7); // used when npc teleports and attacks with a fire field at the same time
invisible", 12); // used when npc turns invisible
music", 24); //used by play music usecode intrinsic


** BG **

crystalball", 10); // crystal ball sprite called by display area usecode intrinsic (Last I knew this was BG only but that may have changed)

Re: My usecode questions

Posted: Thu Apr 29, 2010 11:02 pm
by Malignant Manor
Actually, the map uses shape number so there is no hard coding there. There's likely several more hard coded like 2, 3, and 6 for weather.

Re: My usecode questions

Posted: Sun May 09, 2010 10:54 pm
by Crowley
Now, I'm trying to tie code to when an item is picked up. I figure there must already exist the functionality for that given peoples' reactions to "thievery". It's probably something simple like (event == get_item) or (event == move), but I can't find any mention of that online or in the examples provided.

Re: My usecode questions

Posted: Mon May 10, 2010 2:14 am
by Malignant Manor
You should be able to use usecode eggs like SI does in the Monitor smith.

In this example, they are Criteria->Something on, Flags->Once-only, probability->100, Distance->1, and the usecode tab contains the function called when triggered plus a Quality setting (I'm unsure of its use offhand). Then place the item on top of the egg.



The normal theft reactions are hard coded in the engine. Exult checks if an item is OKAY_TO_TAKE (flag 11) and you are not IN_DUNGEON (flag 23). If there is a witness, they give out warnings until theft_warnings exceed 2 + rand()%3. Then the person attacks if there are no local guards or calls them if there are available.

Usecode function 0x625 (guard shape is object and doubleclick is event) is used when guards arrive.

// calling guards and attacking a thief messages in exultmsg.txt
0x3c:"Stop, thief!"
0x3d:"Thieving scoundrel!"
0x3e:"Guards! Guards!"

text.flx offsets for theft warnings are 0x6e through 0x70.