Jump to content
The Dark Mod Forums

Number wheel doesn't read 0's


Goldwell

Recommended Posts

So I have a number wheel setup and scripted and everything works except if there is a 0 in the code... I'm not that good at scripting but here is the script im using (to avoid spoilers I changed the final code to just four X's but the real one does have a 0 in it that causes it to break)

void wheel_lever(entity lever,boolean bOpen,boolean bLocked,boolean bInterrupted) {

    if (bOpen) {

        lever.setFrobable(0);

        //do something

        vector a=$wheel_one.getAngles();

        vector b=$wheel_two.getAngles();

        vector c=$wheel_three.getAngles();

        vector d=$wheel_four.getAngles();

        float f1,f2,f3,f4,number;

        f1=mod(a_z/36); f2=mod(b_z/36); f3=mod(c_z/36); f4=mod(d_z/36);

        number=f1*1000+f2*100+f3*10+f4;    

        sys.wait(0.5);

        lever.Close();

        lever.setFrobable(1);

if (number == XXXX) sys.trigger($johns_jewelers_unlocksafe);

    }

}
Link to comment
Share on other sites

Does that compile and run ok then? I'm at work so can't check but it looks wrong. Specifically, the use of "mod" doesn't seem right. I'd try it with sys.floor in place of mod, i.e. f1=sys.floor(a_z/36); etc

 

Sorry I guess I should have posted the full script.. I just thought that was the part that mattered.. here is the full script

float mod(float a) {
	if (a<=0){
		a= -a;
	}
	else {
		a= 10-a;
	}
	for (i=0;i<10;i++) {
		if (abs(a-i)<0.1) {
			a=i;
		}
	}
	return a;
}
void wheel_one_up(entity button, boolean bOpen, boolean bLocked, boolean bInterrupted) {
	button.setFrobable(0);
	$numwheel_button_2.setFrobable(0);
	if (bOpen) {
		$wheel_one.rotateOnce('0 0 -36');
		sys.wait(0.3);
	}
	sys.wait(1.5);
	$numwheel_button_2.setFrobable(1);
	button.setFrobable(1);
}

void wheel_one_down(entity button, boolean bOpen, boolean bLocked, boolean bInterrupted) {
	button.setFrobable(0);
	$numwheel_button_1.setFrobable(0);
	if (bOpen) {
		$wheel_one.rotateOnce('0 0 36');
		sys.wait(0.3);
	}
	sys.wait(1.5);
	$numwheel_button_1.setFrobable(1);
	button.setFrobable(1);
}

void wheel_two_up(entity button, boolean bOpen, boolean bLocked, boolean bInterrupted) {
	button.setFrobable(0);
	$numwheel_button_4.setFrobable(0);
	if (bOpen) {
		$wheel_two.rotateOnce('0 0 -36');
		sys.wait(0.3);
	}
	sys.wait(1.5);
	$numwheel_button_4.setFrobable(1);
	button.setFrobable(1);
}

void wheel_two_down(entity button, boolean bOpen, boolean bLocked, boolean bInterrupted) {
	button.setFrobable(0);
	$numwheel_button_3.setFrobable(0);
	if (bOpen) {
		$wheel_two.rotateOnce('0 0 36');
		sys.wait(0.3);
	}
	sys.wait(1.5);
	$numwheel_button_3.setFrobable(1);
	button.setFrobable(1);
}

void wheel_three_up(entity button, boolean bOpen, boolean bLocked, boolean bInterrupted) {
	button.setFrobable(0);
	$numwheel_button_5.setFrobable(0);
	if (bOpen) {
		$wheel_three.rotateOnce('0 0 -36');
		sys.wait(0.3);
	}
	sys.wait(1.5);
	$numwheel_button_5.setFrobable(1);
	button.setFrobable(1);
}

void wheel_three_down(entity button, boolean bOpen, boolean bLocked, boolean bInterrupted) {
	button.setFrobable(0);
	$numwheel_button_6.setFrobable(0);
	if (bOpen) {
		$wheel_three.rotateOnce('0 0 36');
		sys.wait(0.3);
	}
	sys.wait(1.5);
	$numwheel_button_6.setFrobable(1);
	button.setFrobable(1);
}

void wheel_four_up(entity button, boolean bOpen, boolean bLocked, boolean bInterrupted) {
	button.setFrobable(0);
	$numwheel_button_8.setFrobable(0);
	if (bOpen) {
		$wheel_four.rotateOnce('0 0 -36');
		sys.wait(0.3);
	}
	sys.wait(1.5);
	$numwheel_button_8.setFrobable(1);
	button.setFrobable(1);
}

void wheel_four_down(entity button, boolean bOpen, boolean bLocked, boolean bInterrupted) {
	button.setFrobable(0);
	$numwheel_button_7.setFrobable(0);
	if (bOpen) {
		$wheel_four.rotateOnce('0 0 36');
		sys.wait(0.3);
	}
	sys.wait(1.5);
	$numwheel_button_7.setFrobable(1);
	button.setFrobable(1);
}

void wheel_lever(entity lever,boolean bOpen,boolean bLocked,boolean bInterrupted) {
	if (bOpen) {
		lever.setFrobable(0);
		//do something
		vector a=$wheel_one.getAngles();
		vector b=$wheel_two.getAngles();
		vector c=$wheel_three.getAngles();
		vector d=$wheel_four.getAngles();
		float f1,f2,f3,f4,number;
		f1=mod(a_z/36); f2=mod(b_z/36); f3=mod(c_z/36); f4=mod(d_z/36);
		number=f1*1000+f2*100+f3*10+f4;	
		sys.wait(0.5);
		lever.Close();
		lever.setFrobable(1);
           if (number == XXXX) sys.trigger($johns_jewelers_unlocksafe);
	}
}
Link to comment
Share on other sites

In the "mod" function, if a is equal to 0, you get the result 0. Not sure what you're trying to do with it, but turning that <= into a < will likely fix it.

 

Also, please don't call your functions mod. Generally speaking, mod is means modulus, so the moment you write "mod" somewhere, people are going to be thinking about the % operator. Just call it modify or something.

You can call me Phi, Numbers, Digits, Ratio, 16, 1618, or whatever really, as long as it's not Phil.

Link to comment
Share on other sites

In the "mod" function, if a is equal to 0, you get the result 0. Not sure what you're trying to do with it, but turning that <= into a < will likely fix it.

 

Also, please don't call your functions mod. Generally speaking, mod is means modulus, so the moment you write "mod" somewhere, people are going to be thinking about the % operator. Just call it modify or something.

 

Thanks for the response Phi :)

 

I tried changing the <= to just a < but it still didn't respond in game. If I changed the code to 1111 it works fine but as soon as I change one of those numbers to a 0 it stops working. Maybe something script side is broken and it doesn't return the 0 value correctly but seeing as i'm terrible at math and don't know that much about scripting I am just speaking out of my ass haha.

 

As for the mod comment, thanks for the tip but I should note that I didn't actually write the script myself infact I can't remember who did exactly as it's been sitting on my computer for 1-2 years.

Link to comment
Share on other sites

I see. You need a proper modulus. TDM scripting does have one, but it doesn't automatically correct negative numbers by making them positive, so you have to handle that. I'd use this in place of your mod() function:

float getChosenNum(float zAngle)
{
    while ( zAngle < 0 )
    {
        zAngle += 360;
    }
    
    zAngle = zAngle % 360;
    return 10 - sys.floor( zAngle / 36 );
}

... then in the wheel_lever function ...

f1 = getChosenNum(a_z);
f2 = getChosenNum(b_z);
 
etc

Whether or not the "10 minus z_angle/36" calculation is correct will depend on your starting setup. If it doesn't work first time, add a sys.println to your script so it prints out the number every time you pull the lever. That should let you spot the pattern as to what's going on if you get incorrect results.

Link to comment
Share on other sites

I see. You need a proper modulus. TDM scripting does have one, but it doesn't automatically correct negative numbers by making them positive, so you have to handle that. I'd use this in place of your mod() function:

float getChosenNum(float zAngle)
{
    while ( zAngle < 0 )
    {
        zAngle += 360;
    }
    
    zAngle = zAngle % 360;
    return 10 - sys.floor( zAngle / 36 );
}

... then in the wheel_lever function ...

f1 = getChosenNum(a_z);
f2 = getChosenNum(b_z);
 
etc

Whether or not the "10 minus z_angle/36" calculation is correct will depend on your starting setup. If it doesn't work first time, add a sys.println to your script so it prints out the number every time you pull the lever. That should let you spot the pattern as to what's going on if you get incorrect results.

 

That seemed to fix it.. but it was a strange process to get it working.

 

I made the changes to the script as you suggested and at first it didn't work so as per your recommendation I added in the println of the number just before the lever pull checks it. And strangely enough the number that gets printed is completed different to whats displayed on the number pad in game.. so then I decided to set the code on the number pad to what I wanted.. pulled the lever and checked the code displayed in the console (which once again was a completely different number) and then used that console code number in the "if (number == XXXX" part of the script and viola it worked.

 

It all seems a bit strange but the important thing is that it works so that's fine by me! :)

 

Thank you very much for your help!

Edited by Goldwell
Link to comment
Share on other sites

It *would* be possible to get it to give the right answer every time by tweaking the function after a bit of experimentation (if you give me three examples, displayed number plus output I could probably work it out), but it wouldn't work any *better*, it'd just be erm.. tidier :)

Link to comment
Share on other sites

It *would* be possible to get it to give the right answer every time by tweaking the function after a bit of experimentation (if you give me three examples, displayed number plus output I could probably work it out), but it wouldn't work any *better*, it'd just be erm.. tidier :)

 

Ha sure thing man if you want to take a crack at it

 

2673 in game (2101 in console)
0584 in game (11101 in console)
1540 in game (2020 in console)
edit: huh something interesting I found (and I guess actually breaks it)
1540 in game has 2020 in console however 2540 also displays 2020 in the console
Edited by Goldwell
Link to comment
Share on other sites

 

1540 in game has 2020 in console however 2540 also displays 2020 in the console

 

 

 

I think this is because rotateOnce() doesn't produce an exact rotation. Sometimes it stops 0.001 of a degree short, sometimes it goes over by a similar amount. The naive script will count a fraction-over as the next number, so you sometimes get two numbers on the dial mapping to the same output.

 

The way to fix that is to round the result. We seem to be missing a round() function, so you'll need to provide one:

float roundToInt(float n)
{
    float i = sys.floor(n);
    float diff = n - i;
    if ( diff >= 0.5 )
    {
        i += 1;
    }
    return i;
}

float getChosenNum(float zAngle)
{
    while ( zAngle < 0 )
    {
        zAngle += 360;
    }
    
    zAngle = zAngle % 360;
    return 9 - sys.floor( roundToInt(zAngle) / 36 );
}

I also changed the 10- to 9-. 10 was incorrect and it's why one of your results has 5 digits.

 

Lastly, it looks like your dials are using different 0 points. Have you rotated the individual dials to start it with a combination other than 0000? I'm not sure how that could produce the error... Are they showing the same starting angles?

Link to comment
Share on other sites

 

 

I think this is because rotateOnce() doesn't produce an exact rotation. Sometimes it stops 0.001 of a degree short, sometimes it goes over by a similar amount. The naive script will count a fraction-over as the next number, so you sometimes get two numbers on the dial mapping to the same output.

 

The way to fix that is to round the result. We seem to be missing a round() function, so you'll need to provide one:

float roundToInt(float n)
{
    float i = sys.floor(n);
    float diff = n - i;
    if ( diff >= 0.5 )
    {
        i += 1;
    }
    return i;
}

float getChosenNum(float zAngle)
{
    while ( zAngle < 0 )
    {
        zAngle += 360;
    }
    
    zAngle = zAngle % 360;
    return 9 - sys.floor( roundToInt(zAngle) / 36 );
}

I also changed the 10- to 9-. 10 was incorrect and it's why one of your results has 5 digits.

 

Lastly, it looks like your dials are using different 0 points. Have you rotated the individual dials to start it with a combination other than 0000? I'm not sure how that could produce the error... Are they showing the same starting angles?

 

Ok so I just tested your script but it still doesn't seem to be working.

 

I didn't move anything on the number wheel and pulled the lever and it said the code was "9999" so then I tried "0111" on the numberwheel which showed as "9000" in the console.

 

I then tried 1540 and it displayed "909" in the console, I also tried 2540 which displayed "909" in the console also so I think the problem is still present.

Link to comment
Share on other sites

I didn't move anything on the number wheel and pulled the lever and it said the code was "9999" so then I tried "0111" on the numberwheel which showed as "9000" in the console.

These 2 results at least are consistent. They mean the angle needs to be offset by 36 to give the right result.

 

I then tried 1540 and it displayed "909" in the console, I also tried 2540 which displayed "909" in the console also so I think the problem is still present.

This is intriguing. And I can't work out a pattern. Could you do one of following things please? Either:

  1. Get it to print the angles (all 3, xyz) for the wheels as well as the result, and try your tests gain? (0000, 1540, 2540)
  2. Or, export the wheels and lever as a prefab and PM it to me so I can have a play with the matching config in a test map!
Link to comment
Share on other sites

 

These 2 results at least are consistent. They mean the angle needs to be offset by 36 to give the right result.

 

This is intriguing. And I can't work out a pattern. Could you do one of following things please? Either:

  1. Get it to print the angles (all 3, xyz) for the wheels as well as the result, and try your tests gain? (0000, 1540, 2540)
  2. Or, export the wheels and lever as a prefab and PM it to me so I can have a play with the matching config in a test map!

 

 

 

Sent it all via PM, thanks!

Link to comment
Share on other sites

I've sent you a fixed script. There were 3 problems:

  • The rotation was less exact than I thought. Sometimes it was more than half a degree out, so rounding the number of degrees wasn't doing the job. Fixed by rounding after the division by 36.
  • All the results needed 1 adding, as observed above.
  • You had the division by 36 in 2 places. It now happens in the getChosenNum() function, so you don't need to do it in the line where you pass all the angles to that function.

Is there a wiki article containing that script, or explaining how to use the numberlock prefab? I should make one or update it if so.

Link to comment
Share on other sites

That's got it working perfectly and it recognizes the input number correctly.

 

Thanks for your work Steve! :)

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.

  • Recent Status Updates

    • OrbWeaver

      Does anyone actually use the Normalise button in the Surface inspector? Even after looking at the code I'm not quite sure what it's for.
      · 6 replies
    • Ansome

      Turns out my 15th anniversary mission idea has already been done once or twice before! I've been beaten to the punch once again, but I suppose that's to be expected when there's over 170 FMs out there, eh? I'm not complaining though, I love learning new tricks and taking inspiration from past FMs. Best of luck on your own fan missions!
      · 4 replies
    • The Black Arrow

      I wanna play Doom 3, but fhDoom has much better features than dhewm3, yet fhDoom is old, outdated and probably not supported. Damn!
      Makes me think that TDM engine for Doom 3 itself would actually be perfect.
      · 6 replies
    • Petike the Taffer

      Maybe a bit of advice ? In the FM series I'm preparing, the two main characters have the given names Toby and Agnes (it's the protagonist and deuteragonist, respectively), I've been toying with the idea of giving them family names as well, since many of the FM series have named protagonists who have surnames. Toby's from a family who were usually farriers, though he eventually wound up working as a cobbler (this serves as a daylight "front" for his night time thieving). Would it make sense if the man's popularly accepted family name was Farrier ? It's an existing, though less common English surname, and it directly refers to the profession practiced by his relatives. Your suggestions ?
      · 9 replies
    • nbohr1more

      Looks like the "Reverse April Fools" releases were too well hidden. Darkfate still hasn't acknowledge all the new releases. Did you play any of the new April Fools missions?
      · 5 replies
×
×
  • Create New...