Angband.oook.cz
Angband.oook.cz
AboutVariantsLadderForumCompetitionComicScreenshotsFunniesLinks

Go Back   Angband Forums > Angband > Development

Reply
 
Thread Tools Display Modes
Old March 8, 2009, 00:32   #1
will_asher
DaJAngband Maintainer
 
will_asher's Avatar
 
Join Date: Apr 2007
Location: San Antonio, TX
Posts: 1,124
Donated: $10
will_asher is on a distinguished road
another DaJAngband hacking question

I try not to ask for coding help here, but I've wasted most of the day trying to figure this out and can't get it to work right.

I'm modifying the object generation code to catch spellbooks and change it into the type of spellbook that the character can use.

Here's what I put into the get_obj_num(int level) function in object2.c
(in the Process probabilities loop, I included the chest part to show exactly where it is in the code)
Code:
		/* Hack -- prevent embedded chests */
		if (opening_chest && (k_ptr->tval == TV_CHEST)) continue;
		
		/* DAJ: appropriate spellbooks much more likely to appear than others */
	    /* this is a must-have because of having several spell realms */
	
	    /* check for spellbook tval */
	    if ((k_ptr->tval >= TV_MAGIC_BOOK) && (k_ptr->tval < TV_GOLD))
	    {
           /* is it an appropriate spell book? */
           if (!(k_ptr->tval == cp_ptr->spell_book))
           {
              k_ptr->tval = cp_ptr->spell_book;

              /* Hopefully, this will actually change it into the correct spellbook */
              k_idx = lookup_kind(k_ptr->tval, k_ptr->sval);
              
              /* change the index */
              table[i].index = k_idx;
              
		      /* Get the actual kind */
		      k_ptr = &k_info[k_idx];
           }
        }
I don't know what the table[i] stuff means.

In game, this is what happens:
(playing a ranger who uses nature magic)
I get a "Book of Nature Magic []" with the name of a book of a different spell realm in the []. I can cast spells from it as if it were the nature realm spellbook but the name is wrong (and I can't stand giving up on this piece of code when it's this close to working right).
__________________
Will_Asher
aka LibraryAdventurer

My old variant DaJAngband:
http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)
will_asher is offline   Reply With Quote
Old March 8, 2009, 01:38   #2
Nick
Vanilla maintainer
 
Nick's Avatar
 
Join Date: Apr 2007
Location: Canberra, Australia
Age: 58
Posts: 9,526
Donated: $60
Nick will become famous soon enoughNick will become famous soon enough
Quote:
Originally Posted by will_asher View Post
In game, this is what happens:
(playing a ranger who uses nature magic)
I get a "Book of Nature Magic []" with the name of a book of a different spell realm in the []. I can cast spells from it as if it were the nature realm spellbook but the name is wrong (and I can't stand giving up on this piece of code when it's this close to working right).
It could be just a problem with the description (from object1.c) - I would look at the description code first, anyway, as that should point you toward the problem.
__________________
One for the Dark Lord on his dark throne
In the Land of Mordor where the Shadows lie.
Nick is offline   Reply With Quote
Old March 8, 2009, 08:31   #3
Pete Mack
Prophet
 
Join Date: Apr 2007
Location: Seattle, WA
Posts: 6,801
Donated: $40
Pete Mack will become famous soon enough
When you make the assignment to k_ptr->tval, is it pointing to a k_info object? If so, k_ptr should technically be declared
Code:
object_type const *k_ptr;
and the assignment is a big mistake. (You are corrupting the k_info array!)

Yet more evidence that const correctness is a Good Thing...

Last edited by Pete Mack; March 8, 2009 at 08:38.
Pete Mack is offline   Reply With Quote
Old March 9, 2009, 04:19   #4
will_asher
DaJAngband Maintainer
 
will_asher's Avatar
 
Join Date: Apr 2007
Location: San Antonio, TX
Posts: 1,124
Donated: $10
will_asher is on a distinguished road
I guess I should give up on changing the wrong type of spellbook into the right one. I really don't know much about arrays or consts. I was kindof trying to BS it into working because I can't make sense out of it without taking a couple years to actually learn C well.
I wish I could delete this thread now..

I guess I'll just do the much easier thing of making it reject it and start over when it is about to create the wrong type of spellbook.
__________________
Will_Asher
aka LibraryAdventurer

My old variant DaJAngband:
http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)
will_asher is offline   Reply With Quote
Old March 9, 2009, 04:31   #5
Pete Mack
Prophet
 
Join Date: Apr 2007
Location: Seattle, WA
Posts: 6,801
Donated: $40
Pete Mack will become famous soon enough
I'm 99.99% sure that my suggestion was the right one. (I took a look at the source, and k_ptr is pointing to k_idx.)

Here's what is happening:
1. k_ptr is a pointer to the object type in question (a value in k_info.)
2. You assign something to the tval:
Code:
              k_ptr->tval = cp_ptr->spell_book;
3. You do some other stuff, but in the mean time, the tval of k_info[k_idx] has been changed from one magic type to another. After this, there are duplicate values of (tval, sval) in the k_info array. One is the correct one, the other is the one that just got overwritten. That one has the book name (and color, etc) for the other class.

If you want to do this right, do:
Code:
           if (!(k_ptr->tval == cp_ptr->spell_book))
           {
              /* k_ptr->tval = cp_ptr->spell_book;   OH, NO, MR BILL!!!!!!!!!! */

              /* This _will_ locate the correct spellbook. */
              /* NOTE: this probably a mistake for Kelek getting changed to 
               * Word of God, because Kelek is a lot more common, and shallower. */
              k_idx = lookup_kind(cp_ptr->spell_book, k_ptr->sval);
              
              /* change the index */
              table[i].index = k_idx;
              
		      /* Get the actual kind */
		      k_ptr = &k_info[k_idx];
           }
EDIT:
This kind of error wouldn't occur if the various _info arrays were declared const, with non-const overrides during initialization in info2.c.

However, it would mean a lot of code churn to make the various _ptr values agree on const correctness.
Pete Mack is offline   Reply With Quote
Old March 9, 2009, 06:11   #6
will_asher
DaJAngband Maintainer
 
will_asher's Avatar
 
Join Date: Apr 2007
Location: San Antonio, TX
Posts: 1,124
Donated: $10
will_asher is on a distinguished road
Quote:
Originally Posted by Pete Mack View Post
I'm 99.99% sure that my suggestion was the right one. (I took a look at the source, and k_ptr is pointing to k_idx.)
According to what you're saying, I was closer than I thought. When you said that I'm corrupting the array I thought that meant that I was doing it completely wrong, but I guess I misunderstood.

Quote:
Originally Posted by Pete Mack View Post
Here's what is happening:
1. k_ptr is a pointer to the object type in question (a value in k_info.)
2. You assign something to the tval:
Code:
              k_ptr->tval = cp_ptr->spell_book;
3. You do some other stuff, but in the mean time, the tval of k_info[k_idx] has been changed from one magic type to another. After this, there are duplicate values of (tval, sval) in the k_info array. One is the correct one, the other is the one that just got overwritten. That one has the book name (and color, etc) for the other class.

If you want to do this right, do:
Code:
           if (!(k_ptr->tval == cp_ptr->spell_book))
           {
              /* k_ptr->tval = cp_ptr->spell_book;   OH, NO, MR BILL!!!!!!!!!! */

              /* This _will_ locate the correct spellbook. */
              /* NOTE: this probably a mistake for Kelek getting changed to 
               * Word of God, because Kelek is a lot more common, and shallower. */
              k_idx = lookup_kind(cp_ptr->spell_book, k_ptr->sval);
              
              /* change the index */
              table[i].index = k_idx;
              
		      /* Get the actual kind */
		      k_ptr = &k_info[k_idx];
           }
thanks a lot for the help

Quote:
Originally Posted by Pete Mack View Post
/* NOTE: this probably a mistake for Kelek getting changed to
* Word of God, because Kelek is a lot more common, and shallower. */
Why didn't I think of that? Maybe I should rethink this and go back to just having it reject the wrong book (for a different reason than not being able to my code to work)..
I have an alchemy/misc realm used by alchemists, thieves, and archers. Books 7, 8, and 9 have the same depth and rarity (depth 60, rarity 2), but one is used only by alchemists, one used only by archers, and one used only by thieves. Obviously that would be bad if a depth 60 9th book was converted to a 9th book of another realm. I really should've thought of that..
I guess if I'm going to make the spells of those three classes that much separate, it would be more correct just to make them each have their own realm with less books in those three realms and then I could use the code you suggested. Or maybe I could just make it reject alchemy realm books if the player is not an alchemist, archer, or thief, and convert the books of other realms to the correct one..

But I can use what I learned here whether I actually use this bit of code or not.
__________________
Will_Asher
aka LibraryAdventurer

My old variant DaJAngband:
http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)
will_asher is offline   Reply With Quote
Old March 9, 2009, 07:51   #7
Pete Mack
Prophet
 
Join Date: Apr 2007
Location: Seattle, WA
Posts: 6,801
Donated: $40
Pete Mack will become famous soon enough
Quote:
According to what you're saying, I was closer than I thought. When you said that I'm corrupting the array I thought that meant that I was doing it completely wrong, but I guess I misunderstood.
Well, yes and no. "Corrupting" means writing garbage (bogus values) into some place you don't expect. It almost always means a severe bug, but it also usually means that you did something that looks "almost" correct. Sometimes it's very subtle and takes a long time to debug, or even to detect.
Pete Mack is offline   Reply With Quote
Old March 9, 2009, 08:00   #8
Pete Mack
Prophet
 
Join Date: Apr 2007
Location: Seattle, WA
Posts: 6,801
Donated: $40
Pete Mack will become famous soon enough
Quote:
I guess if I'm going to make the spells of those three classes that much separate, it would be more correct just to make them each have their own realm with less books in those three realms and then I could use the code you suggested. Or maybe I could just make it reject alchemy realm books if the player is not an alchemist, archer, or thief, and convert the books of other realms to the correct one..
Your idea is fundamentally sound. In V Rogues more or less can't use MB6 and MB9, but nonetheless share realms with mages and rangers. The right way to do it is to make sure the wrong books don't get generated in the first place, or you will start running into frequency errors like the Kelek->Wrath of God problem. Note that this will still cause problems with money, as out-of-depth books will never be found for Warriors. But since you are using eddie's gold system, IIRC, that is a good thing.
Pete Mack is offline   Reply With Quote
Old March 9, 2009, 08:18   #9
PaulBlay
Knight
 
Join Date: Jan 2009
Posts: 657
PaulBlay is on a distinguished road
Is this sort of thing why find_inven is used in Angband's store.c with
Code:
static int find_inven(const object_type *o_ptr)
?

I couldn't work out what that 'const' was for.
__________________
Currently turning (Angband) Japanese.
PaulBlay is offline   Reply With Quote
Old March 9, 2009, 08:25   #10
Pete Mack
Prophet
 
Join Date: Apr 2007
Location: Seattle, WA
Posts: 6,801
Donated: $40
Pete Mack will become famous soon enough
@Paul:

Yes. It's a hint that says: the incoming value to this function will never be affected by this function. And if you accidentally do something like the tval problem above, the compiler will complain.

See, for example:
http://en.wikipedia.org/wiki/Const_correctness

Last edited by Pete Mack; March 9, 2009 at 08:35.
Pete Mack is offline   Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
DaJAngband hacking: help with the code (please, I wont ask much!) will_asher Variants 19 April 21, 2008 01:41
DaJAngband -I'm in over my head will_asher Idle chatter 15 February 27, 2008 09:04
Announce: DaJAngband v1.0.03 will_asher Variants 4 February 6, 2008 20:23
DaJAngband: new object question will_asher Variants 4 December 13, 2007 03:18
Stat hacking Old Man Vanilla 1 October 12, 2007 15:13


All times are GMT +1. The time now is 08:08.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2023, vBulletin Solutions Inc.