Advanced Exult programming topic...

NOTICE: This forum is archived as read only.
Please use the Github Discussions at https://github.com/exult/exult/discussions
Forum rules
NOTICE: This forum is archived as read only.
Please use the Github Discussions at https://github.com/exult/exult/discussions
Locked
tetzlaff
Posts: 38
Joined: Thu May 14, 2020 1:34 pm

Advanced Exult programming topic...

Post by tetzlaff »

I wanted to add a feature to show signs/plaque info on a single click. I noticed that when a signed is double clicked it runs the USECODE which called the code to paint the sign. Finally it waits for a mouseclick.

I was thinking if I wanted to get the sign data with the least amount of code I would call usecode with a special event number that returns a pointer or a global pointer. It seems messy. Is there another way to get at the sign data?
drcode
Site Admin
Posts: 2267
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by drcode »

I can't think of any way off-hand. The actual sign text is stored in the usecode, referenced by the sign's 'quality' field.
tetzlaff
Posts: 38
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by tetzlaff »

DrCode,

I uploaded a patch to display sign names on a single click... Actually this is just a part of the "extended info" on single click code I ultimately want to write. Please check if this is an appropriate way to extract the sign name.

Thanks!
wjp
Site Admin
Posts: 1708
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by wjp »

Did you check if any of the sign usecode functions have undesirable side effects?
tetzlaff
Posts: 38
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by tetzlaff »

I dont quite follow you....

What I did was rather long and a bit messy and uses 2 global variables.

To invoke the special usecode, I first set a global semiphore to "true". I then called obj->action(). The usecode then executes a new branch of code and actually ignores the original branch ("false"). I then set the global semiphore back to "false". And then attach the "sign name" to the obj with add_text_effect.

The messy part was the extraction of the sign name. Its broken up into 2 parts. Part 1 decodes runic characters into a string. Then the second part changes the case of each character.

I was rather pleased with the results. For the first time I was quickly able to read street signs and building signs. If you have time, please take a look at my code.

In the meantime, I found an actual bug and confirmed it against the original gameplay. When your in a building with the doors shut, you can double click the signs outside to read them. In the original it said "blocked". I will work on that bug next. I noticed it because I was thinking to not decode the sign's name but write "sign" if your "blocked". What do you think?
wjp
Site Admin
Posts: 1708
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by wjp »

You're calling usecode in places where the original did not run usecode. This means that if that usecode has side-effects (setting flags, playing sound effects, showing visual effects or even more complex things), they'll get triggered at a time where they would not have been triggered in the original. That would be bad.

Therefore, you need to make sure that this doesn't happen.
tetzlaff
Posts: 38
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by tetzlaff »

I am not sure if there is any other "use code" areas I need to be aware of, but I took the intrinsics.cc file and added a "cout >>>>>>>> start sign usecode
intrinsic (get_avatar_ref)
intrinsic (get_npc_name)
intrinsic (get_item_quality)
intrinsic (display_runes)
>>>>>>>>> end sign usecode

metal plaque on ground
>>>>>>>>> start sign usecode
intrinsic (get_item_quality)
intrinsic (get_avatar_ref)
intrinsic (get_npc_name)
intrinsic (display_runes)
>>>>>>>>> end sign usecode

hanging metal plaque facing east
>>>>>>>>> start sign usecode
intrinsic (get_item_quality)
intrinsic (get_avatar_ref)
intrinsic (get_npc_name)
intrinsic (display_runes)
>>>>>>>>> end sign usecode

hanging metal plaque facing south
>>>>>>>>> start sign usecode
intrinsic (get_item_quality)
intrinsic (get_avatar_ref)
intrinsic (get_npc_name)
intrinsic (display_runes)
>>>>>>>>> end sign usecode
Gradilla Dragon
Posts: 468
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by Gradilla Dragon »

Ok, now go to LB castle and click on the sign that reads "The Throne Room of Lord British". Nothing strange there? Now activate the Hack Mover, place Lord British under the sign and click on it again to see what happens.
- Gradilla Dragon
tetzlaff
Posts: 38
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by tetzlaff »

I guess.... well... my single click showed the name on the plaque... and killed the king... hmmmm.....

You know I knew about that "feature" for a long long time, and I never even thought about it until you mentioned it. Are there other places in the game where signs can trigger events?

For the record, there were 38 intrinsic printouts in my stdout.txt for that event.

Well, I guess I could say my feature makes it just that much easier to pick off the King! Is that really that bad?
Gradilla Dragon
Posts: 468
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by Gradilla Dragon »

Well, that is exactly what wjp was talking about. Do you follow now? :)
- Gradilla Dragon
tetzlaff
Posts: 38
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by tetzlaff »

I follow... and when I looked at all the code that is called to paint a book... I gave up my dream to print the title on a single click :(

On a side note, wjp, I found that if you delete line number 2287 of gamewin.cc, then the game play is more inline with the original. If a sign is blocked on the original, then the word "blocked" is shown. The line of code is "!Is_sign(obj->get_shapenum()) &&"

Do I need to submit a patch for bug fixes this trivial?

Thanks,
wjp
Site Admin
Posts: 1708
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by wjp »

Hm, I wonder why that's there. Anyway, yes, better submit a patch so that we don't forget about it (I don't have time to look at it properly right now). Thanks.
drcode
Site Admin
Posts: 2267
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by drcode »

Perhaps a better way to implement 'single-click' for signs would be to write a new usecode function that just returns the text. I'm a bit nervous about trying to hack around the existing code by adding flags.

It shouldn't be too hard for us to distribute our own compiled usecode 'patch', and have Exult load it automatically.
tetzlaff
Posts: 38
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by tetzlaff »

DrCode,
I know you mentioned something about distrubuting a new usecode to fix some "known" bugs in the original U7 too... Can the usecode return pointers in the way its implimented right now? I dont remember "->action" passing any variables or returning any.

I will say this, if there is anyway to get that feature into the game, I am willing to try it. I really like it a lot.
Wizardry Dragon
Posts: 1241
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by Wizardry Dragon »

While it's very commendable that people are attempting to patch Exult, I am compelled to chant the mantra "If it ain't broke, don't fix it."

Especially in this case, as changing signs like that is stepping on my usecode's feet more than a little >_<

- Wizardry Dragon
Cheers, Wizardry Dragon
Lead Designer, Ultima VII: The Feudal Lands
www.thefeudallands.ca
Wizardry Dragon
Posts: 1241
Joined: Thu May 14, 2020 1:34 pm

Re: Advanced Exult programming topic...

Post by Wizardry Dragon »

In addition, setting flags is a very messy way to implement signs. As I understand this would require a section of game flags simply for signs, and there are a *LOT* of signs in Ultima VII.

A more graceful way would be to have something say like this (and this is pseudocode, so dont try to compile it or anything)

displaySign(Gump_id, sText)

sign1000_click()
{
displaySign(wooden_sign, "This is a sign, interesting isnt it?)
}

And of course then just encapsulate the Usecode call to display a gump with the specified text in displaySign()

- Wizardry Dragon
Cheers, Wizardry Dragon
Lead Designer, Ultima VII: The Feudal Lands
www.thefeudallands.ca
Locked