Jump to content

Clearing out shops?


Recommended Posts

It would be nice, though.

 

I wanted to create a random item shop like in E3/BoE. And before anyone asks, yes, I already know how to place random items in the shop. Here's the code I was using:

Code:
variables;short x;...beginstate INIT_STATE;...x = 0;while (x < 500) {  //(hopefully) remove all possible items	add_item_to_shop(6,x,-10);	x = x + 1;}x = 0;while (x < 25) {  //add random items	add_item_to_shop(6,get_ran(5,1,90),20);	if (get_ran(10,0,10) < 50)		x = x + 1;		else x = x + 2;}...break;
The trick was, of course, to have the code remove the items, and then create a new group of random items every time the party entered the town. I got the idea for using a negative number for how many of the item to place from the following line in the editor documentation appendix pertaining "add_item_to_shop":
Quote:
Note that, in all cases, you will want to put a number above 0 for how_many. If you don't, the item will disappear from the store.
However, every negative number I've tried for how_many in the reset portion ends up creating an empty shop.

 

When I use 0 for how_many in the reset portion, it does work, sort of. The code creates the initial set of items just fine, but then gets a little weird. When I reenter the town, the code adds more random items to the shop (provided there's space), and if a randomly generated item is already in the shop, the code adds the amount in how_many to what's already there.

Link to comment
Share on other sites

Oh, yeah, I'd forgotten using a negative value for the how_many parameter.

 

So are you saying that if you try to clear the whole shop and then put more random stuff items in, at the end there's just nothing? (I may do some testing myself if I et some time.)

 

A possible optimization, although I fear it likely wouldn't solve the problem above, if I understand it correctly, would be to store which item types were randomly chosen the last time in a set of SDFs and just erase those item types. It would cost you up to twice as many SDFs as there will be item types in the store, but would save a lot of loop iterations during the erase step.

Link to comment
Share on other sites

Originally Posted By: Niemand
Oh, yeah, I'd forgotten using a negative value for the how_many parameter.

So are you saying that if you try to clear the whole shop and then put more random stuff items in, at the end there's just nothing? (I may do some testing myself if I et some time.)
Sort of. In theory, my code was supposed to clear the shop, and then restock it with a new set of random items.

In practice, I tried to "play computer" with the code I used, and I think I found the problem (or, more accurately, a problem) with the logic. What I was doing was filling up the shop with negative items 0 through 24; since the how_many parameter gave each item a negative quantity, they wouldn't display. Once this was done, I was trying to move random items numbered 25 and above into the shop. Therefore, the code would always show an empty shop, because there was always a negative quantity of all the items within. I could still sell items, though, which I found a bit surprising.
Quote:
by Ishad Nha
I had a stab at that with my port of Akhronath's River and Leaf, it used a lot of space in the scenario script.
See the Lyceum post:
http://thelyceum.yuku.com/topic/1911

by Niemand
A possible optimization, although I fear it likely wouldn't solve the problem above, if I understand it correctly, would be to store which item types were randomly chosen the last time in a set of SDFs and just erase those item types. It would cost you up to twice as many SDFs as there will be item types in the store, but would save a lot of loop iterations during the erase step.
@Ishad Nha:
I skimmed the post, and the concept has a lot of merit. I copied it (thank God for copy & paste), and plan to go over it in more detail.

@Niemand:
I agree that it can be optimized, and maybe to an even higher degree than you're suggesting. I took a handful of programming classes when I was in college; fortunately for this situation, the instructor's main emphasis was creating efficient code, regardless of language. I'll dig out some of my old notes on flowcharting and give it a shot. (In fact, as I was typing this, I already started to get ideas.)
Link to comment
Share on other sites

Quote:
In practice, I tried to "play computer" with the code I used, and I think I found the problem (or, more accurately, a problem) with the logic. What I was doing was filling up the shop with negative items 0 through 24; since the how_many parameter gave each item a negative quantity, they wouldn't display. Once this was done, I was trying to move random items numbered 25 and above into the shop. Therefore, the code would always show an empty shop, because there was always a negative quantity of all the items within. I could still sell items, though, which I found a bit surprising.

This is about what I was afraid might be the case, namely that giving an item a negative quantity in a shop merely hides it but doesn't free up the slot so that a positive quantity of some other item can be put in. If this really is what happens, then we're stuck, since there's no way to actually get items out of the shop except for the party to buy them. However, from jeff's documentation, it's ambiguous whether the former (simple hiding), or the latter (proper removal) happens.

(Aside: I'd guess that the real difference is made in the logic for adding a positive number of an item, specifically how it determines whether a slot in the shop is free to be overwritten or not. Given how Jeff usually does this, I would have expected what I called 'proper removal' above to work.)

Quote:
I could still sell items, though, which I found a bit surprising.

This has been a feature of the game engine for some time, probably back into the original trilogy: you can sell items to a full shop, they are just lost and so can't be bought back.

Quote:
I agree that it can be optimized, and maybe to an even higher degree than you're suggesting. I took a handful of programming classes when I was in college; fortunately for this situation, the instructor's main emphasis was creating efficient code, regardless of language. I'll dig out some of my old notes on flowcharting and give it a shot. (In fact, as I was typing this, I already started to get ideas.)

Sure, and I'd be curious to hear them. It probably doesn't matter too much in this case, since the script only runs on occasion, rather than every tick or something, but given how slow Avernumscript is, good algorithms can be pretty vital (at least when it's possible to implement anything non-trivial at all), and you never know when a good trick may come in handy later. I'm not sure what else to do in this case besides delete only items added previously and then fuse the loops, but maybe you can think of something more interesting I've missed. smile You could get really silly and pack the stored item numbers more densely into SDFs (for 25 9-bit item numbers you could use only 29 SDFs, rather than 50) but the operations to do the packing and unpacking would be horrifically complicated and therefore slow, for only modest space savings.

EDIT: I finished reading Ishad Nha's article; it looks like he assumes that you just want to keep the shop full, only replenishing it when items are bought. He also introduces the idea of assigning different weights to different items, which is generally desirable but has the downside of bloating the code.
Link to comment
Share on other sites

Actually, what I came up with is absolutely tiny compared to Ishad Nha's code. I still use 50 SDFs, but what I did is much, much simpler.

 

I decided to forgo Ishad Nha's first three methods (Shopping Demiplanes, multiple begin_talk_node calls, and the pay_coins/reward_give combo); they all add far too much complexity. Instead, I went with the basic idea behind the fourth:

Quote:
All Magic Shop inventories are truly random. Items are generated by the use of the get_ran call, then the item numbers are compared with a list of corresponding Stuff Done Flag values

As Ishad Nha mentions, you need two SDFs if you want random items with a number higher than 255. Therefore, I used 2 sets of SDFs: one to store item numbers up to 255, and one to allow for item numbers greater than 255 (if needed).

 

I rewrote the routines I started with, and changed where they were called somewhat. Here's the new code, in all its miniscule glory:

Code:
variables;short a,b,c;...beginstate INIT_STATE;a = 1;while (a <= 25) {	b = get_ran(5,1,90);	add_item_to_shop(5,b,20);	if (b > 255) {  //SDFs max out at 255, and must be split up		c = b - 255;		b = 255;		}		else c = 0;	//set flags	set_flag(1,a,;	set_flag(2,a,c);	if (get_ran(10,0,10) < 50)		a = a + 1;		else a = a + 2;	}...beginstate EXIT_STATE;a = 1;while (a <= 25) {	if (get_flag(1,a) > 0)  //if there is an item, clear it		add_item_to_shop(5,get_flag(1,a) + get_flag(2,a),-20);	//reset flags	set_flag(1,a,0);	set_flag(2,a,0);	a = a + 1;	}
This entire snippet is approximately 30 lines of code, and replaces hundreds.

 

I haven't had the chance to test it yet, but it (hopefully) should work. The idea is to fill the random item shop when you enter a town, and clear it out when you leave.

Link to comment
Share on other sites

Yes, Avernumscript is not as flexible as it might be, so a lot of circumlocution is needed.

My method of weighting is one that I know of to create an inventory as would be found in an Exile Magic Shop.

Another is, you could assign special classes to magic items in the scenario data script and then give certain special class items a higher chance of being generated for the stock.

This could be used to enable your idea to remove certain items from the shop. Special class is one of the few item properties that can be used outside the data script.

Link to comment
Share on other sites

Actually, I suspect your method is more complex than an Exile Junk Shop. I haven't actually looked at the relevant snippet of code, so I could be mistaken, but I think Exile Junk Shops just pick random items from the item list with a particular treasure class, without having different weight for different items.

 

In other words, Exile Junk Shops have no weighting whatsoever.

Link to comment
Share on other sites

I just tried the code I posted above; it doesn't work. Well, it does add items to the shop, but it won't take them away. If only there were a call like this:

Code:
void remove_item_from_shop(short which_shop,short which_item);
That would make things infinitely easier.

 

@Ishad Nha: Does your code remove items from a shop? I don't seem to see a routine for it anywhere; if it's there, your item weighting algorithm appears to be hiding it.

Link to comment
Share on other sites

All these shops are based upon the Exile magic item shops, I don't see them as being game-breaking.

Does my code remove items from shops? No, it does not, that was not a problem that I addressed.

If you wanted to do it, it is easy enough, increment the flag every time the item is generated, until you reach a cut-off point: #. Then the item is no longer added to the shop menu.

Original code:

if ((a >= 343) && (a <= 346)) {

set_flag(t,i,0);

set_flag(t,i + 10,1);

}

altered code:

if ((a >= 343) && (a <= 346)) {

if (get_flag(t,i) < #) {

set_flag(t,i,0);

set_flag(t,i + 10,1);

inc_flag(t,i,1);

}

}

 

In theory, you could simplify the code by the use of Special Classes, but there are no suitable Ascript calls for this occasion, the only calls are:

short char_has_item_of_class_equip(short char_num,short which_class,short take_item)

short has_item_of_class(short which_class,short take_item)

short item_of_class_on_spot(short loc_x,short loc_y,short what_class)

short take_all_of_item_class(short which_class,short gold_to_pay)

short take_item_of_class_on_spot(short loc_x,short loc_y,short what_class)

Edit:

If you are only removing a few items, it might be simpler to use a second shop inventory without the items, as was suggested above. Or you could just sell the items through dialog nodes rather than a shop menu.

 

Link to comment
Share on other sites

Originally Posted By: Ishad Nha
All these shops are based upon the Exile magic item shops, I don't see them as being game-breaking.

Clearly, you did not exploit the random item shops in E2 and E3 to supply everyone in your party with Rings and Boots of Speed, Rings of Resistance, Mithral Chain, Runed Helms, twin Magic Wave Blades, etc etc.
Link to comment
Share on other sites

Originally Posted By: Niemand
In addition, a very simple refinement is to skip ranges of high powered items when filling the shop so that there won't be anything to unbalancing for sale.

Anyone willing to abuse the game mechanics in such a clear manner would probobly just cheat with or without random item shops, so I would just go for them anyways.
Link to comment
Share on other sites

Eh, I don't think so. I think there's a continuum of cheating that ranges from "avoids sandwich time and does not affect the game" (like "exitzone") to "makes something that could theoretically happen, happen without waiting for a 1 in whatever chance" (like abusing save-and-reload on the lower end, or like the item-shop-restock trick in the middle, to generating pokemon with perfect genes on the higher end) to "makes something happen that cannot or is not supposed to happen in the game" (like the free money trick or abusing the Tower of Magi donation box). There is, I suppose, a perpendicular continuum ranging from "exploiting unintended poor balance" to "exploiting bugs" to "using developer-made cheat codes" to "editing the game files".

Link to comment
Share on other sites

Originally Posted By: CRISIS on INFINITE SLARTIES
Eh, I don't think so. I think there's a continuum of cheating that ranges from "avoids sandwich time and does not affect the game" (like "exitzone") to "makes something that could theoretically happen, happen without waiting for a 1 in whatever chance" (like abusing save-and-reload on the lower end, or like the item-shop-restock trick in the middle, to generating pokemon with perfect genes on the higher end) to "makes something happen that cannot or is not supposed to happen in the game" (like the free money trick or abusing the Tower of Magi donation box). There is, I suppose, a perpendicular continuum ranging from "exploiting unintended poor balance" to "exploiting bugs" to "using developer-made cheat codes" to "editing the game files".


I'm not passing judgement on cheaters here. I cheat heavily myself sometimes. I'm just saying that if you have someone who's willing to abuse an exploit based on getting random items clearly not intended for characters of that level through shops, they probably won't suddenly become perfect players if you remove the shops- they'll just use the editor. So "it makes the game unbalanced because people can exploit it" is really a useless criticism, because people will either find something else to exploit or just cheat other ways.
Link to comment
Share on other sites

Originally Posted By: CRISIS on INFINITE SLARTIES
I already had this argument over on the Basilisk forums, and it wasn't productive, so I'm just going to say that I disagree, that I think there is a meaningful distinction, and leave it at that.


Yes, but the difference is arguing at the basilisk forums dosen't increase you post count here tongue.

Fine, we'll just agree to disagree, if you wish.
Link to comment
Share on other sites

Originally Posted By: Metatron
Why don't you NOT have a random item shop? I think this is an elegant, optimized solution.
Actually, I was planning on one, but what I wanted was a shop that reset itself with a different set of random items each time I entered the town. However, since this would be nearly impossible, and I'm not going to ask Jeff to rewrite the game for my sake, I guess I'll just have to settle for one set of random items in the shop for now, and work on resetting the shop later.

In the scenario I'm doing for the 1/10 contest, I was planning to have a cameo of myself as the owner of a random item shop, and have it work similar to E3/BoE.
Originally Posted By: Ishad Nha
Does my code remove items from shops? No, it does not, that was not a problem that I addressed.
No wonder I couldn't find it; I'll stop looking then.
Originally Posted By: CRISIS on INFINITE SLARTIES
Clearly, you did not exploit the random item shops in E2 and E3 to supply everyone in your party with Rings and Boots of Speed, Rings of Resistance, Mithral Chain, Runed Helms, twin Magic Wave Blades, etc etc.
That's the point: 1 exploited random shop = 6 nearly-unstoppable tanks = gringringringringringrin.
Link to comment
Share on other sites

Originally Posted By: The Mystic
I guess I'll just have to settle for one set of random items in the shop for now, and work on resetting the shop later.
Well, you could do something like adding one more item every time the party enters town (which would only have an effect if the shop is not already full)... though, this assumes that when you buy all of an item that a new item can be inserted in its place. Still, that's probably the case, right?
Link to comment
Share on other sites

Originally Posted By: Dantius
I'm just saying that if you have someone who's willing to abuse an exploit based on getting random items clearly not intended for characters of that level through shops, they probably won't suddenly become perfect players if you remove the shops- they'll just use the editor.


I disagree. On this, I think it's more about "opportunist cheating", if you like. If I see an item in a store that's clearly too powerful for my party (see the purchasable skills in RoR, that bow from Canopy, or the free levels of melee in TENG), I will buy/get it, without a doubt. If those items aren't available though, I'm not going to go into the editor/alter game files to give myself that stuff. I don't even think it's cheating, really - it's taking advantage of an oversight by the designer.

However these oversights *are* unbalancing. A designer might balance his scenario knowing that his players might have overpowered weapons. When that party leaves that scenario and goes into another that isn't balanced for god-like items, it pisses all over the balancing work the second designer did. I guess some responsibility is on the player not to take advantage of the overpowered items, or to spam-refresh random item shops, but as a designer I've learnt one thing: players are jerks and it's your job to make sure they don't have the option of ruining yours, and everybody elses, hard work.
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...