Using GetRandomInt for multiple conditions

lightwriter
What I mean is something like this where it only does 1 of the conditions and not try to do multiple ones of them:
1. 10% chance | 1-10
2. 25% chance | 11-35
3. 30% Chance | 36-65
4. 25% Chance | 66-90
5. 10% Chance | 91-100
So I'm trying to do this using the RandomGetInt but I'm having trouble with limiting it to the specified number ranges.
I tried using and statements but don't think I'm doing it properly.

The Pixie
There are a number of ways of doing that. Here is one:
n = GetRandomInt(1, 100)
if (n <= 10) {
msg("option 1")
}
else if (n <= 35) {
msg("option 2")
}
else if (n <= 65) {
msg("option 3")
}
else if (n <= 90) {
msg("option 4")
}
else {
msg("option 5")
}

lightwriter
See, I don't get an error from that like the more complicated way I was using but it still doesn't do anything...
basically I'm trying to change the value of something using a formula that has a different chance of varying.
Basically, with the the random items restocking thing, only now trying to get somewhat of a random price by using a value.
item.price = item.value * (a number that varies)

TinFoilMkIV
can you share the code that you're currently using? Might help to give us a better idea where the problem is.

lightwriter
Here's the code for the script:
//Lots of this code was created by Pixie
// Gets the integer for random price
produceprice1 = GetRandomInt (1,100)
// remove old stock from the shop
foreach (produce1, GetDirectChildren(foodstock)) {
produce1.parent = foodstorage
}
foreach (produce2, GetDirectChildren(foodstock)) {
produce2.parent = foodstorage
}
//Item 1
for (produce1, 1, 5) {
l = GetDirectChildren(foodstorage)
n = GetRandomInt(0, ListCount(l)-1)
produce1 = ObjectListItem(l, n)
produce1.parent = foodstock
}
if (produceprice1 <= 10) {
produce1.price = produce1.value * 0.5
}
else if (produceprice1 <= 35) {
produce1.price = produce1.value * 0.75
}
else if (produceprice1 <= 65) {
produce1.price = produce1.value
}
else if (produceprice1 <= 90) {
produce1.price = produce1.value * 1.25
}
else {
produce1.price = produce1.value * 1.5
}
// Item 2
for (produce2, 1, 5) {
l2 = GetDirectChildren(foodstorage)
n2 = GetRandomInt(0, ListCount(l2)-1)
produce2 = ObjectListItem(l2, n2)
produce2.parent = foodstock
}
produce1.price = round(produce1.price)

TinFoilMkIV
If I'm reading this right 'produce1' is a variable that references a specific object during your stock/unstock scripts.

It seems to me that you're likely only referencing the final 'produce1' when you set the value, as you loop through several objects that are added to the stock, but only the final one is still considered 'produce1' at the time of the price change.

So in other words, you need to include the script to set the price during the stocking script, to set each items price as it is being put into stock.

EDIT: going to attempt to write this up in psuedo-code for ease of readability, also adding some notes to see if I'm even correct about whats happening
//Item 1
for (P, 1, 5) {
l = GetDirectChildren(foodstorage) //list of storage items that can be put into stock
n = GetRandomInt(0, ListCount(l)-1) //random list index selected
produce1 = ObjectListItem(l, n) //produce1 = current selection
produce1.parent = foodstock //move produce1 to stock
//set price of produce1 here
//if you don't set the price here then you need to reference all possible items and set their price individually elsewhere
}
//at this point produce1 = the last item moved to stock only


Also noted that syntax for the 'for' script is
for(<iterator variable>,<int from>,<int to>

the problem here is that you're using your object variable 'produce1' as your iterator, which isn't a good idea as each loop you're setting it to an integer, or potentially breaking the for loop, I'm not entirely sure how thats handled, but either way, not a good idea outside specific cases where your iterator is always holding an integer value to begin with.

the iterator can be anything and is generally local to the for script so that's potentially a problem area.

lightwriter
that fixed it to a certain extent but every single time it is the same amount as the value. Yes, that one is the highest likely 1 but I never see another price.

TinFoilMkIV
found a few points of issue and edited them into my last post. I was adding that before your followup post so I'll just go over the points I found here.

overview of the problems
-outside the for() segment, produce1 only references the last produce1 that was put into stock, not all of them.
-price would probably be best set during the stocking phase
-you're using produce1 as your iterator variable for the for(), I honestly don't know how quest handles this being set to an object value, best not to even have that potential wierdness.

lightwriter
alright, so, basically I have to each item manually

TinFoilMkIV
you can put the price set in the loop where you add them to the stock, if you do it at that time you can just set it once but it will repeat for each item when it goes into the stock.

HegemonKhan
I'm a bit unclear of what you want, but if you want to have each item, set to a random price, here's how:

foreach (placeholder_variable, Object_name.List_Attribute_name) {
placeholder_variable.Attribute_name = GetRandomInt (min, max)
}


example:

foreach (shop_item, shop.itemlist) {
if (shop_item.type_of_object = "claymore_sword") {
shop_item.price = GetRandomInt (100,500)
} else if (shop_item.type_of_object = "full_plate_mail") {
shop_item.price = GetRandomInt (1000,5000)
}
}


a lot of people are confused by, what I like to call it as, the 'placeholder_variable' to try to help explain it, here's a really good analogy example that explains it (and the 'foreach' Function itself too):

game.team = split ("joe;jim;jill;john;jan;jen",";")

foreach (team_member, game.team) {
invoke (team_member, "run_laps")
// the 'team_member' is used to represent each of the items in the list, so conceptually, it is doing this:
// invoke (team_member{joe}, "run_laps")
// invoke (team_member{jim}, "run_laps")
// invoke (team_member{jill}, "run_laps")
// invoke (team_member{jan}, "run_laps")
// invoke (team_member{jen}, "run_laps")
// aka, all the team members, each individually, run laps (a Script Variable, that is invoked)
}


~OR (the 'placeholder_variable' can be labelled whatever you want, see below) ~

foreach (fhkasdhfkjashfkl, game.team) {
invoke (fhkasdhfkjashfkl, "run_laps")
}


foreach (x, game.team) {
invoke (x, "run_laps")
}


foreach (item, game.team) {
invoke (item, "run_laps")
}


foreach (itm, game.team) {
invoke (itm, "run_laps")
}


foreach (obj, game.team) {
invoke (obj, "run_laps")
}

lightwriter
For GetRandomInt (#, #) can I use a variable as one of the random integers.
Like
x = item.value * .5
y = item.value *1.5
item.price = GetRandomInt(x, y)

The Pixie
Yes.

jaynabonne
Not like that. GetRandomInt takes ints, and multiplying by a number with a decimal will give you a double (even if the original number is even in the above case).

However, you can do this:

x = cast(item.value * .5, int)
y = cast(item.value *1.5, int)
item.price = GetRandomInt(x, y)

to cast the values back to an integer.

Assuming your value is originally an integer, you might be better off doing this instead:

x = item.value/2
y = item.value*3/2
item.price = GetRandomInt(x, y)

which is only integer arithmetic and avoids the need for a cast.

lightwriter
ok, thanks!

The Pixie
jaynabonne wrote:Not like that. GetRandomInt takes ints...

Oops, had not spotted they were not ints.

lightwriter
Why am I getting this error?
Error running script: Error compiling expression 'stockeditem.stockvalue < stockeditem.value + 25': CompareElement: Operation 'LessThan' is not defined for types 'String' and 'Int32'

stockeditem is a defined variable and I checked to see if the attributes were set to integer for the objects that the variable stands for and they are...
does GetDirectChildren turn all attributes into strings? If so,is there a work around for this?

jaynabonne
The error is saying that stockeditem.stockvalue is a string. Perhaps you assigned it a value in your script somewhere? Attributes morph to the type you assign to them. Even if the attribute is an integer at startup, if you assign a string to it at some point in your code, it will then be a string. You can see the current attribute values by using the debugger.

(And, no, GetDirectChildren doesn't turn attributes into strings. Only you can do that. :) )

lightwriter
I almost got it working, now I want to exclude the player so they don't get moved.
foreach (stockeditem, GetDirectChildren(myshop)) 

I'm basically making a game where you own a shop and get stock by buying from other shops where they stock randomly generated items at random price values that change as time moves on.

HegemonKhan
to move your items (Objects) in 'myshop' (Room Object) but not your 'player' Player Object:

full logic-conceptual actual (but impractical) example:

foreach (stockeditem, GetDirectChildren(myshop)) {
if (not stockeditem.name = "player") {
stockeditem.parent = your_destination_Object's_name
msg (stockeditem.name + " is transferred to...")
// or, if you give them aliases: msg (stockeditem.alias + " is transferred to...")
} else if (stockeditem.name = "player") {
msg ("You're not an item, so you're not transferred to ....")
}
}


logic-practical actual example (we don't need to say that the 'player' isn't transferred, only need to transfer the items and to inform the person of it):

foreach (stockeditem, GetDirectChildren(myshop)) {
if (not stockeditem.name = "player") {
stockeditem.parent = your_destination_Object's_name
msg (stockeditem.name + " is transferred to...")
// or, if you give them aliases: msg (stockeditem.alias + " is transferred to...")
}
}


or, maybe~probably you don't even want to inform the person of it (as it is an underlying game functionality):

foreach (stockeditem, GetDirectChildren(myshop)) {
if (not stockeditem.name = "player") {
stockeditem.parent = your_destination_Object's_name
}
}

jaynabonne

if (not stockeditem.name = "player") {



You can also just do:

if (not stockeditem = player) {

or if you have a different pov object:

if (not stockeditem = game.pov) {

TinFoilMkIV
Another thing to consider is if you plan to have any object that isn't a player or stock item in the shop at any point. If that can happen it will probably be better to just save the items to a list as you stock them and for the item removal just go down the list and put them back in stock instead of trying to manually exclude any non-items in the shop.

jaynabonne
You could also inherit all stockable items from a type (e.g. "stockable") and then use DoesInherit to see if they're in the right category.

This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums