Need help with random results in RPG (Solved)

Started by beomoud, Fri 23/11/2007 17:19:52

Previous topic - Next topic

beomoud

O.K. So, i've been building my first RPG and i have been using stats just like DnD but i find difficulties when i try to roll the tests. At this point i try to have my PC lockpick a door, so he uses his lockpicks and rolls: lockpick_test = Nimbleness + Lockpicking + Random(10)
(I'm using the Advanced Randoms Module).

He has Nimbleness:5, Lockpicking:2 and he rolls a d10, the difficulty to beat is 10, but each time he attempts the result is always between 7,8,9.

Now can anyone tell me what is wrong with my code? I've been working on this for a while now and gone through the entire manual. Here it is:

Script Header:

int Nimbleness = 5;
int Lockpicking;
short lockpick_test;
bool locked;
import function lockpicking (short door_defense);

Global Script:

// main global script file 
function lockpicking (short door_defense){
  lockpick_test = Nimbleness + Lockpicking + Random(10);
  if (lockpick_test >= door_defense){
locked = false;
return locked;
Display("You rolled a %d you picked the lock", lockpick_test);
}
else Display ("You rolled a %d you couldn't pick the lock", lockpick_test);
}

Room Script:

// room script file
int dest;
int dest1;                (these are irrelevant, it's just so that you can see the whole script)

#sectionstart hotspot1_a  // DO NOT EDIT OR REMOVE THIS LINE
function hotspot1_a() {
  // script for Hotspot 1 (Hotspot 1): Interact hotspot
if (locked == false){
Display ("You go to another room");
}
else
Display ("The door is locked");
}
#sectionend hotspot1_a  // DO NOT EDIT OR REMOVE THIS LINE

#sectionstart hotspot2_a  // DO NOT EDIT OR REMOVE THIS LINE
function hotspot2_a() {
  // script for Hotspot 2 (Hotspot 2): Use inventory on hotspot 
RandomBoundries (1, 10);
lockpicking (10); 
}
#sectionend hotspot2_a  // DO NOT EDIT OR REMOVE THIS LINE

#sectionstart room_c  // DO NOT EDIT OR REMOVE THIS LINE
function room_c() {
  // script for Room: First time player enters room 
}
#sectionend room_c  // DO NOT EDIT OR REMOVE THIS LINE

Khris

Flying over the code, I spotted two things:

-Inside the lockpicking function, you are returning before the message is displayed. Remove the "return locked;" line.
-locked is never set to true in the first place.

And some general advice: use proper indentation; it'll make things more readable and bugs more unlikely.

beomoud

I changed it to this and for some unknown reason it has solved my random numbers problem  but i still don't seem to be able to get the "You go to another room" message as soon as you interact with the open door, it doesn't recognize it as open. I changed it to:

// main global script file 
function lockpicking (short door_defense){
  lockpick_test = Nimbleness + Lockpicking + Random(10);
  if (lockpick_test >= door_defense){
open = true;
Display("You rolled a %d you picked the lock", lockpick_test);
return open;
}
else Display ("You rolled a %d you couldn't pick the lock", lockpick_test);
}

============================================================

(i also changed locked to open everywhere i should so that i don't have to declare "locked =  true " to start with)

Radiant

Add a Display() command in there to find out what the present values of Nimbleness, Lockpicking, and door_defense are.

Khris

#4
I noticed something:
You're declaring the variables in the script header. This will create a different variable for each room.
Move the locked declaration to the room script.

Try this:
Code: ags
//script header
import int Nimbleness;
import int Lockpicking;

import function lockpicking (int door_defense);


Code: ags
// main global script file 
int Nimbleness = 5;
int Lockpicking;              // = 2; ?
export Nimbleness, Lockpicking;

function lockpicking (int door_defense) {
  int lockpick_test = Nimbleness + Lockpicking + Random(9)+1;  // dice: 1-10
  if (lockpick_test >= door_defense) {
    Display("You rolled a %d and successfully picked the lock.", lockpick_test);
    return true;                 // exits function
  }
  Display ("You rolled a %d and failed at picking the lock.", lockpick_test);
  return false;
}


Code: ags
// room script file
int dest;
int dest1;
bool locked=true;      // this room's door

#sectionstart hotspot1_a  // DO NOT EDIT OR REMOVE THIS LINE
function hotspot1_a() {
  // script for Hotspot 1 (Hotspot 1): Interact hotspot

  if (locked) Display ("The door is locked");
  else Display ("You go to another room");
}
#sectionend hotspot1_a  // DO NOT EDIT OR REMOVE THIS LINE

#sectionstart hotspot2_a  // DO NOT EDIT OR REMOVE THIS LINE
function hotspot2_a() {
  // script for Hotspot 2 (Hotspot 2): Use inventory on hotspot 

  if (player.ActiveInventory==iLockpick) {        // added check for correct item
    if (locked) {
      RandomBoundries (1, 10);
      if (lockpicking(10)) locked=false;   // lockpicking succeeded -> unlock door
    }
    else Display("This door is already unlocked.");
  }
  else Display("I can't use that here."); 
}
#sectionend hotspot2_a  // DO NOT EDIT OR REMOVE THIS LINE

#sectionstart room_c  // DO NOT EDIT OR REMOVE THIS LINE
function room_c() {
  // script for Room: First time player enters room 
}
#sectionend room_c  // DO NOT EDIT OR REMOVE THIS LINE


Note that the lockpicking function returns true if the lockpicking was successful, false if it wasn't.
Also note that you're using Random() which is the built-in AGS function, not the one from the module.

Edit: thanks, Ashen; code is fixed.

beomoud

I don't know who you are man but you are a scripting magician, thank you for getting in the trouble to go through my code. I hadn't completed all the parts,  but i believe i would have if i could get over this bump. I got lost with the "return" keyword, i still haven't figured out exactly how to work with this.

Well it works, smoothly thanks. About randomness, so... i'm not using advanced random? Could i just erase the module (i thought RandomBoundries was an Advanced Random asset), also where did you find the Random function in the first place, i'm pretty sure it's not in the manual as i have gone throught it many times, are you all reading some other tutorial or something?
Anyway thanks

Ashen

#6
RandomBoundaries() is an Advanced Randoms function, yes. However, you're not actually doing anything with it - you just have RandomBoundaries(1, 10); on a line by itself. It looks like you might be trying to set a random value for door_defense, which would be lockpicking(RandomBoundaries(1, 10)), but at the moment it just generates a value which is ignored.

Anyway, if that's all you're using from the Advanced Random module, having the module might be a bit redundant. As Khris shows in the lockpicking function, it can be replaced with 1 + Random(9); (In fact, I'm pretty sure all the function does is return min + Random (max-min);.) Of course if you're using the other advanced features elsewhere, you might as well use RandomBoundaries since it's there.

And Random definitely is in the manual.

One thing about Khris' code - unless I'm misreading it, the Display("This door is already unlocked."); line will also run if the door IS locked (i.e. " You failed to pick the lock" "This door is already unlocked" - which might be a bit confusing). Make it else Display("This door is already unlocked.");, and that should clear up.
I know what you're thinking ... Don't think that.

Khris

Yup, I've corrected code.

beomoud:
The return keyword is used to exit the function early or return a value (or both).
E.g. if a function isn't supposed to do something but to calculate something, you can return the result of the calculation:

Code: ags
function max(int a, int b) {
  if (a>b) return a;
  return b;
}


Calling max(3, 5); will return 5; to put this into a variable, you'd use
int m = max(3, 5);
Note that the function doesn't contain an "else"; if return a; is encountered, the rest of the function is ignored.

A function can return ints only; that's due to "function" really being a substitute for "int".
If you want to return something else, you can do it like this:

Code: ags
float root(float x, int y) {
  float result;
  // calculate x to the power of 1/y
  return result;
}


You can use this function like a standard float variable in your code:
float my_result = 3.0 * root(1.2, 3);

SMF spam blocked by CleanTalk