Pages: 1
  Print  
Author Topic: action_move  (Read 9947 times)
Offline (Female) IsmAvatar
Posted on: November 03, 2010, 10:44:10 am

LateralGM Developer
LGM Developer
Location: Pennsylvania/USA
Joined: Apr 2008
Posts: 877

View Profile Email
I'm trying to write up the action_move function, since it doesn't really have a direct GML equivalent, due to the direction argument being multiple-choice which then gets randomly selected.
I'm also working on an educated assumption here, trying to recall from when I still had access to GM, how it behaved.

Assumption 1: It will randomly select one of the depressed directional buttons, but will not select a between value (so the resulting direction will always be a multiple of 45).
Assumption 2: The directional string directly corresponds with the directions in the dirs array. (I've done a bit of testing, so I think it is correct)

Code: (C++) [Select]
void action_move(const char dir[9], int argspeed) {
 int dirs[9] = {  225, 270, 315, 180, -1, 0, 135, 90, 45 };
 int chosendirs[9];
 int choices = 0;
 for (int i = 0; i < 9; i++)
  if (dir[i] == '1') chosendirs[choices++] = dirs[i];
 if (choices == 0) return;
 choices = int(random(choices)); //choices is now chosen

 //We use rval.d for efficiency, so hspeed/vspeed aren't set twice.
 const double newdir =
 ((enigma::object_planar*)enigma::instance_event_iterator->inst)->direction.rval.d = chosendirs[choices];
 if (argument_relative)
  argspeed += ((enigma::object_planar*)enigma::instance_event_iterator->inst)->speed;
 const double newspd =
 ((enigma::object_planar*)enigma::instance_event_iterator->inst)->speed.rval.d = chosendirs[choices] == -1 ? 0 : argspeed;
 ((enigma::object_planar*)enigma::instance_event_iterator->inst)->hspeed.rval.d = newspd * cos(newdir);
 ((enigma::object_planar*)enigma::instance_event_iterator->inst)->vspeed.rval.d = newspd * sin(newdir);
}

Note 1: The first argument should always be an array of characters of size 9. Longer strings are fine, but only the first 9 characters will be examined. Shorter strings may cause this to look at memory beyond the string.
Note 2: This code makes use of the random(x) function.

Note 3: A few minor optimizations can be made around random.
3a: To avoid the use of random when there's only 1 choice. Replace:
 choices = int(random(choices)); //choices is now chosen
With
Code: (C++) [Select]
if (choices == 1) choices = 0;
else choices = int(random(choices)); //choices is now chosen
3b: Replace random with randomInt if it's more efficient (and if it exists).
3c: Replace random with integrated choose() function once it's implemented, if it's more efficient.
« Last Edit: November 12, 2010, 12:17:35 pm by IsmAvatar » Logged
Offline (Male) RetroX
Reply #1 Posted on: November 03, 2010, 03:57:55 pm

Master of all things Linux
Contributor
Location: US
Joined: Apr 2008
Posts: 1055
MSN Messenger - classixretrox@gmail.com
View Profile Email
Instead of using a string of 9 bytes, why not just use unsigned char with flags?

Code: [Select]
const unsigned char e  = 1;
const unsigned char ne = 2;
const unsigned char n  = 4;
const unsigned char nw = 8;
const unsigned char w  = 16;
const unsigned char sw = 32;
const unsigned char s  = 64;
const unsigned char se = 128;
Logged
My Box: Phenom II 3.4GHz X4 | ASUS ATI RadeonHD 5770, 1GB GDDR5 RAM | 1x4GB DDR3 SRAM | Arch Linux, x86_64 (Cube) / Windows 7 x64 (Blob)
Quote from: Fede-lasse
Why do all the pro-Microsoft people have troll avatars? :(
Offline (Female) IsmAvatar
Reply #2 Posted on: November 03, 2010, 04:25:54 pm

LateralGM Developer
LGM Developer
Location: Pennsylvania/USA
Joined: Apr 2008
Posts: 877

View Profile Email
Because the DND action direction argument is passed as a string of 9 bytes. Changing it would require a change in the underlying mechanism, and then a backwards compatibility mechanism to get it to still work with GM.
Logged
Offline (Male) RetroX
Reply #3 Posted on: November 03, 2010, 04:55:52 pm

Master of all things Linux
Contributor
Location: US
Joined: Apr 2008
Posts: 1055
MSN Messenger - classixretrox@gmail.com
View Profile Email
Oh.

In that case, never mind.
Logged
My Box: Phenom II 3.4GHz X4 | ASUS ATI RadeonHD 5770, 1GB GDDR5 RAM | 1x4GB DDR3 SRAM | Arch Linux, x86_64 (Cube) / Windows 7 x64 (Blob)
Quote from: Fede-lasse
Why do all the pro-Microsoft people have troll avatars? :(
Offline (Male) Josh @ Dreamland
Reply #4 Posted on: November 04, 2010, 12:06:06 am

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
I don't know off the top of my head the implications of taking const char[9] as a parameter; I am relatively certain that's the same as just const char*. Whatever the actual case, you really wanted const char[10] for the NULL at the end of the literal. :P

My other beef is that, despite this being a function instead of a macro, it does not take advantage of non-EDL optimizations; namely setting direction.dval and speed.dval manually, then manipulating hspeed.dval and vspeed.dval manually.

I'm actually too tired and lazy right now to do the trivial amount of text insertion required to put that to code. >.<

-sigh-

Code: (C++) [Select]
const double dir = ((enigma::object_planar*)enigma::instance_event_iterator->inst)->direction.dval = chosendirs[choices];
((enigma::object_planar*)enigma::instance_event_iterator->inst)->speed.dval = chosendirs[choices] == -1 ? 0 : argspeed;
hspeed.dval = speed.dval * cos(dir), vspeed.dval = speed.dval * sin(dir);

Assuming all the rest of your code is right, and that I'm remembering the name of my own class member correctly.
« Last Edit: November 04, 2010, 12:07:41 am by Josh @ Dreamland » Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Female) IsmAvatar
Reply #5 Posted on: November 04, 2010, 12:08:08 pm

LateralGM Developer
LGM Developer
Location: Pennsylvania/USA
Joined: Apr 2008
Posts: 877

View Profile Email
The [9] was to emphasize that only 9 characters will be considered. I'm not sure if that'd cause any problems for the null at the end or not, but I don't even look at the null; it doesn't matter to me.

As for macro, good luck writing that. I also haven't been able to get #define to work quite right in definitions for defining dnd actions. It's like it gets ignored.

As for hspeed and vspeed, I wasn't sure how that worked.

As for whether the rest of the code is right, I've already been using it for a while in a new catch-the-clown d&d version, and it works great.
« Last Edit: November 04, 2010, 12:15:26 pm by IsmAvatar » Logged
Offline (Male) Josh @ Dreamland
Reply #6 Posted on: November 04, 2010, 12:17:03 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
- Like I said, shouldn't matter.
- Until choose is implemented, the macro isn't possible.
- Well, now you know. Have you implemented it?
- (Y)
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Female) IsmAvatar
Reply #7 Posted on: November 04, 2010, 01:27:25 pm

LateralGM Developer
LGM Developer
Location: Pennsylvania/USA
Joined: Apr 2008
Posts: 877

View Profile Email
Implemented that (it's rval.d, not dval).
I also made a couple more notes about the use of random.
Logged
Offline (Female) IsmAvatar
Reply #8 Posted on: November 12, 2010, 12:00:33 pm

LateralGM Developer
LGM Developer
Location: Pennsylvania/USA
Joined: Apr 2008
Posts: 877

View Profile Email
I just realized that action_move has a relative checkbox. I'm investigating what it does right now. Assuming that it only effects the speed, insert this:

 if (argument_relative)
  argspeed += ((enigma::object_planar*)enigma::instance_event_iterator->inst)->speed;

right before
 const double newspd =


Edit: Investigation complete. It does only effect the magnitude, and magnitudes set with the Stop direction are not retained. I've implemented this into the code.
« Last Edit: November 12, 2010, 12:19:11 pm by IsmAvatar » Logged
Pages: 1
  Print