Moving carts

Error message

Deprecated function: implode(): Passing glue string after array is deprecated. Swap the parameters in drupal_get_feeds() (line 394 of /var/www/pied-piper.ermarian.net/includes/common.inc).

Pages

AuthorTopic: Moving carts
Warrior
Member # 4792
Profile #0
Hello. I am not quite certain if this is the correct board to be posting to, but I had a question in regards to scripting.

If one wanted to make multiple creatures move back and forth along long paths which would take many twists and turns, how would one go about that? The character must always travel in a straight line and never fidget or waver inbetween two waypoints. I'm trying to move mining carts along railroad tracks. This would need to be called continuosly while a party was in a town. So far I've been able to figure everything I've needed to do, but this one seems to be beyond me. I'll keep trying, but if someone has any ideas, I'd really appreciate them. I can't use waypoints as there are too many turns by too many carts. And the move_to_loc_x_y is quite odd. My carts just stop halfway there.
Posts: 57 | Registered: Wednesday, July 28 2004 07:00
Warrior
Member # 250
Profile #1
Hmm, if I had to guess I would say that move_to_loc_x_y isn't working because the distance between the creature and the destination is to far for the pathfinding to work right. One way to do this I think, although it would be a big pain to code and may be to resource intensive, and would have to be hardcoded (meaning you need a specific script for each unique path although each one beyond the first should be much easier) would be to do the following

In the start state of the creature script, in a large amount of if then statments check its x,y location. At certain x,y locations, the creature script would change the number of one of the memory cells. You should have these locations not to far apart. Now the rest of the start state, would be dedicated to more if then statements, checking for the number in the memory cell. It would then take the number in the memory cell, and use that to tell the cart the way to the next x,y location that is recognized. (move_to_loc_x_y should work for small distances) Since you want them to go forward and back, instead of a loop as far as I can tell, have a second memory cell, that changes at either end and would represent the direction currently traveled.

Of course the real problem, is that such a script would take a large amount of time to write, as you have to manually write in each x,y location to check for, and where to go to next. Also if you have a second path a different cart needs to go by, you would have to create another copy of the script, and change the values so it goes on its own path.

Of course I've probably didn't get my idea across clearly enough and I would wait to see if anyone else had an idea that would be easier to implement.

One last thing, that I think might be a small problem no matter what approach you use is that unless you dictate the carts movement space by space, if a party member or other creature stood along the path, the cart would probably go off the track to pathfind around it. Can't think of a good way around this. Lining both sides of the track with blocked to creatures spaces would stop it from going off track, and would make giving the directions much easier, but it would make it almost impossible to use regular creatures in the same area.
Posts: 61 | Registered: Saturday, November 3 2001 08:00
Warrior
Member # 4987
Profile Homepage #2
Waypoints, thats all I have to say
Posts: 60 | Registered: Sunday, September 19 2004 07:00
Agent
Member # 2820
Profile #3
You have their scripts acting even while the party is at a distance, right?

Unless there is something blocking them from reaching their destination, the move_to_loc_x_y call should cause the affected monster to move there directly, regardless of current distance from the location.

Waypoints would definitely make things easier, but I think you can only have 8 per town.

Our ability to fine tune and work closely with the pathing engine is very limited because of the lack of pathing calls, and the engine cannot calculate complex paths (nor any extra requirements for said paths).

Because of this, making these moving cart creatures will be difficult. Finding a way to call a stop_moving function every time an obstruction is encountered would make things run in a stuttered, yet functioning fashion. But barring these tracks from the player would be the easiest course of action.

If these carts are unnecessary to the scenario, have them just visible to the player to add atmosphere, but make only a few of them. They would be generally inaccessible to the party.

[ Monday, October 11, 2004 20:09: Message edited by: Garrison ]

--------------------
Thuryl: I mean, most of us don't go around consuming our own bodily fluids, no matter how delicious they are.
====
Alorael: War and violence would end if we all had each other's babies!
====
Drakefyre: Those are hideous mangos.
Posts: 1415 | Registered: Thursday, March 27 2003 08:00
Warrior
Member # 4792
Profile #4
Thank you very much, both Linthar and Garrison. It's weird, because I started coding it exactly the way Linthar said about an hour after I posted. Weird, huh? Anyways, I have yet to test it, but I think it should work. I'm not entirely certain how I can get them to go back, but I have an idea. See, to differentiate each direction, I incremented a variable for each new path call. I think I can go backwards by subtracting one without having to re-enter all the x,y coordinates. It was very much a pain the first time I did it, and this will be the third such change I've done on that scale.

Just a sidenote: Garrison is correct in saying that the documentation provided says only eight. However, you can place ten in the game. I tried editing the source code for more, but the box can't fit more than one digit, and I have no idea how to change that.

Oh, and I was wondering; do you think that I need to manually code something to stop the cart if something obstructs it's path?

Thanks again for your help.
Posts: 57 | Registered: Wednesday, July 28 2004 07:00
Agent
Member # 2820
Profile #5
Yes, because there is no way for the carts to take into consideration that they are not supposed to stray off their tracks. A stop_moving() call should suffice.

--------------------
Thuryl: I mean, most of us don't go around consuming our own bodily fluids, no matter how delicious they are.
====
Alorael: War and violence would end if we all had each other's babies!
====
Drakefyre: Those are hideous mangos.
Posts: 1415 | Registered: Thursday, March 27 2003 08:00
Warrior
Member # 4792
Profile #6
Well, I tried my code, and it did not work. I've gone over it several times and I can't figure it out. I would like to post it here to see if anyone can find the error. Meanwhile, I'll keep searching.
if
(dist_to_loc(get_memory_cell(4),get_memory_cell(5)) > 0) // checks to see if cart there
move_to_loc_x_y(ME,get_memory_cell(4),get_memory_cell(5)); // if not, goes there
else if
((0 < i < 15) && (ME == 10)) { // if there, calculate next route for cart #10
set_memory_cell(4,x);
set_memory_cell(5,y);
i = i + 1;
}
else if
((29 > i > 14) && (ME == 13)) {
stop_moving(ME);
set_memory_cell(4,x);
set_memory_cell(5,y);
i = i + 1;
}
else while
((36 > i > 28) && (ME == 14)) {
stop_moving(ME);
set_memory_cell(4,x);
set_memory_cell(5,y);
i = i + 1;
}
else while
((42 > i > 35) && (ME == 15)) {
stop_moving(ME);
set_memory_cell(4,x);
set_memory_cell(5,y);
i = i + 1;
}
else while
((54 > i > 41) && (ME == 16)) {
stop_moving(ME);
set_memory_cell(4,x);
set_memory_cell(5,y);
i = i + 1;
}
else while
((63 > i > 53) && (ME == 17)) {
stop_moving(ME);
set_memory_cell(4,x);
set_memory_cell(5,y);
i = i + 1;
}
else while
((68 > i > 62) && (ME == 18)) {
stop_moving(ME);
set_memory_cell(4,x);
set_memory_cell(5,y);
i = i + 1;
}
else while
((81 > i > 67) && (ME == 19)) {
stop_moving(ME);
set_memory_cell(4,x);
set_memory_cell(5,y);
i = i + 1;
}

if // sample paths
(i == 1) {
x = 55;
y = 53;
}
if
(i == 2) {
x = 52;
y = 53;
}
if
(i == 3) {
x = 52;
y = 49;
}
if
(i == 4) {
x = 57;
y = 49;
}
if
(i == 5) {
x = 57;
y = 40;
} // 400 lines more of this
I set i = 1 in INIT_STATE, and I set mem_cells 4 and 5 to the carts starting location in INIT_STATE. I also declared the variables, if you were wondering.
Posts: 57 | Registered: Wednesday, July 28 2004 07:00
Warrior
Member # 4987
Profile Homepage #7
Now, not to sound lazy or discouraging, but seriously, work around it. Is this a hostile town? If so why would people still be pushing carts around (Unless they're magical). How many carts do you plan on having? Do you realize how much memory it will take up just have the minor cool effect? Death at Chapmans had some cool sound effects in the school, and it screwed the entire level over because of the memory it ate.
Posts: 60 | Registered: Sunday, September 19 2004 07:00
Warrior
Member # 4792
Profile #8
Hmm, I just noticed I posted the wrong code. Only the first nine lines of the initial if statement are valid. I hadn't changed the rest to match yet. The i,x,y statements are ok, though.

I don't think it will take up too much memory, as I am having the carts only act at a distance. That may be a bit unrealistic however. And this is a friendly town. And the carts are magical. And there are eight carts. I may have to keep them stationary, but until everything else has been exhausted, I'm not ready to give up.
Posts: 57 | Registered: Wednesday, July 28 2004 07:00
Agent
Member # 2820
Profile #9
ME always equals -1. You have to use my_number() for the conditionals that try to determine which cart the script is running for.

Multiple comparisons cannot be placed together (a < b < c). This is not a user friendly scripting engine! If this is possible in C, then that is news to me.

After skimming through the heart of the script, I think that it has some unneeded complexity in it. This causes making it work correctly more difficult. This may already be the best way of doing it, but I would have to think more about this in order to give you a definitive answer.

--------------------
Thuryl: I mean, most of us don't go around consuming our own bodily fluids, no matter how delicious they are.
====
Alorael: War and violence would end if we all had each other's babies!
====
Drakefyre: Those are hideous mangos.
Posts: 1415 | Registered: Thursday, March 27 2003 08:00
Warrior
Member # 4792
Profile #10
I've revised my code and, as I have done before, I anticipated some of the problems that Garrison points out. Very odd coincidences. Here is a revised sample of the code:
if
(dist_to_loc(get_memory_cell(4),get_memory_cell(5)) > 0)
move_to_loc_x_y(ME,get_memory_cell(4),get_memory_cell(5));
else if
((i <= 14) && (my_number() == 10)) {
i = i + 1;
set_memory_cell(4,x);
set_memory_cell(5,y);
}
else if
((i >= 15) && (i <= 28) && (my_number() == 13)) {
i = i + 1;
set_memory_cell(4,x);
set_memory_cell(5,y);
}
if
(i == 1) {
x = 55;
y = 53;
}
if
(i == 2) {
x = 52;
y = 53;
}
if
(i == 3) {
x = 52;
y = 49;
}
I figured out the ME thingy, but instead of the far simpler way of my_number, I had assigned a preset memory cell to the creature number. The multiple comparisons I had also changed previously, but I had no idea why. It gave me no error when testing, which, sadly, none of this does. However, I was running out of ideas and though that did not solve the problem entirely, at least it was constructive. The carts, as of this post, still sit there. Argh. I'm going to bed.
Posts: 57 | Registered: Wednesday, July 28 2004 07:00
...b10010b...
Member # 869
Profile Homepage #11
If you're not getting any errors, are you sure the script is being called at all?

I find that adding print_str calls in various places is an excellent debugging tool, since it tells you which parts of the script BoA is actually running and when.

[ Thursday, October 14, 2004 00:32: Message edited by: Thuryl ]

--------------------
The Empire Always Loses: This Time For Sure!
Posts: 9973 | Registered: Saturday, March 30 2002 08:00
Warrior
Member # 4792
Profile #12
I love you, Thuryl! I would have never thought of that, and it turned out several portions were not being called. This gave way to a massive overhual of my script and scenario. I simplified the scenario so that the carts did not intersect, ever. This required deletion of three carts, which drastically reduced the amount of script. Then I rewrote the script into a new format, consisting of one big if statement.

After several hours testing this, however, I'm lost again (really, this doesn't happen often). Thanks to Thuryl, I know that my last else statement is not getting called. It just keeps calling the first if "bit". I can get it to call the else, but it only calls it once and then returns to repeating the if "bit". And this without moving. I'm just not sure why it won't move. Here is the code, if I could ask for your,(forum members), help once more. I'm going to post almost all of it this time, to get a better view.
// something2.txt
// Neither simple, nor naive, this text has the creature follow a certain route.
// Memory Cells:
// Cell 1,2 - Stuff done flag. If both 0, nothing. Otherwise when this
// is killed, set to 1. (Example: If cell 1 is 3 and cell 2 is 5, when
// creature is killed, sets SDF(3,5) to 1.)
// Cell 3 - Dialogue node to start with if talked to. if left at 0, this
// character doesn't talk.
// Cell 4 - X coordinate to move to.
// Cell 5 - Y coordinate to move to.

begincreaturescript;

variables;

short i = 1;
short target;
short x = 0;
short y = 0;

body;

beginstate INIT_STATE;

break;

beginstate DEAD_STATE;
// Set the appropriate stuff done flag for this character being dead
if ((get_memory_cell(1) != 0) || (get_memory_cell(2) != 0))
set_flag(get_memory_cell(1),get_memory_cell(2),1);
break;

beginstate START_STATE;
// Start ifs for cart #13
if
(i == 1) {
x = 52;
y = 53;
}
if
(i == 2) {
x = 52;
y = 49;
}
if
(i == 3) {
x = 57;
y = 49;
}
if
(i == 4) {
x = 57;
y = 40;
}
if
((dist_to_loc(get_memory_cell(4),get_memory_cell(5)) > 0) && (i <= 13) && (i != 0) && (my_number() == 13)) {
print_str("Testing 1.0");
move_to_loc_x_y(my_number(),get_memory_cell(4),get_memory_cell(5));
}
else if
((dist_to_loc(get_memory_cell(4),get_memory_cell(5)) > 0) && (i >= 14) && (i <= 18) && (my_number() == 15)) {
print_str("Testing 1.1");
move_to_loc_x_y(my_number(),get_memory_cell(4),get_memory_cell(5));
}
else if
((dist_to_loc(get_memory_cell(4),get_memory_cell(5)) > 0) && (i <= 26) && (i >= 19) && (my_number() == 17)) {
print_str("Testing 1.2");
move_to_loc_x_y(my_number(),get_memory_cell(4),get_memory_cell(5));
}
else if
((dist_to_loc(get_memory_cell(4),get_memory_cell(5)) > 0) && (i <= 30) && (i >= 27) && (my_number() == 18)) {
print_str("Testing 1.3");
move_to_loc_x_y(my_number(),get_memory_cell(4),get_memory_cell(5));
}
else if
((dist_to_loc(get_memory_cell(4),get_memory_cell(5)) > 0) && (i <= 40) && (i >= 31) && (my_number() == 19)) {
print_str("Testing 1.4");
move_to_loc_x_y(my_number(),get_memory_cell(4),get_memory_cell(5));
}
else {
print_str("Testing A");
i = i + 1;
set_memory_cell(4,x);
set_memory_cell(5,y);
}

break;

beginstate TALKING_STATE;
if (get_memory_cell(3) == 0) {
print_str("It's a cart. It doesn't talk.");
end();
}
break;

Posts: 57 | Registered: Wednesday, July 28 2004 07:00
Agent
Member # 2820
Profile #13
I am sorry for my ignorance, but I can't figure out exactly what these carts look like when in motion. Why doesn't the incrementing 'i' variable throw everything off? Wouldn't the coordinates set at the beginning be changed on the very next turn?

--------------------
Thuryl: I mean, most of us don't go around consuming our own bodily fluids, no matter how delicious they are.
====
Alorael: War and violence would end if we all had each other's babies!
====
Drakefyre: Those are hideous mangos.
Posts: 1415 | Registered: Thursday, March 27 2003 08:00
Warrior
Member # 4792
Profile #14
Well, in theory, no. The initial if statement should only allow the else statement to be called if the cart is at an x,y coordinate. The carts can't move until they have coordinates in mem_cell 4 and 5. When the script is first run, there is nothing there and i = 0. I'm not sure if that makes the get_memory_cell() call false, but to ensure it, I place the i != 0. Since it is false, it goes to the else statement. This is the tricky part.
The first else statement does not set anything for the mem_cells. It only increments i. Wait, hold on. The light just went on! I know what I did wrong! Yippee! I think that the program beleives that nothing in mem_cells 4 and 5 is a number. It can't go to nothing, but the statement is true. This doesn't cause it to keep incrementing. Rather, it just keeps trying to go to 0,0 (the status of the mem_cells). Well, inadvertenly, Garrison, you have helped me greatly. My thanks to you. I think what I should do is kill the (i != 0) in the first part, and manually enter in the first coordinates for each cart. I'll let you know if this works. Thanks again.
Posts: 57 | Registered: Wednesday, July 28 2004 07:00
Warrior
Member # 4792
Profile #15
Ok, it did not work. This is the twentieth hour I have been working on this creature script with no success. I now officially hate BoA. Yet I persist.
Posts: 57 | Registered: Wednesday, July 28 2004 07:00
Warrior
Member # 4792
Profile #16
Ha ha ha ha ha ha ha! Mua ha ha ha ha ha ha! She lives!

Whew, glad to get that out of my system. The 32 hour mark has just passed and I have it working. It does not slow down gameplay, or demand heavily of the processor (I should know, I run a 533mHz Celeron). The last, small bug, is that whenever the party moves in the way of the cart, everything is messed up and the cart goes wacko. I have given each cart it's own creature script, which, though annoying, seemed necessary. They are all identical except for the coordinates.

Here is a portion of the shortest one:
// Start checking for cart position and then give cart directions for next destination
if
(i == 1) {
x = 9;
y = 43;
}
if
(i == 2) {
x = 9;
y = 34;
}
if
(i == 3) {
x = 11;
y = 34;
}
if
(i == 4) {
x = 9;
y = 34;
}
if
(i == 5) {
x = 9;
y = 43;
}
if
(i == 6) {
x = 6;
y = 43;
}
if
(i == 7) {
x = 6;
y = 54;
}
if
(i == 8) {
i = 0;
x = 6;
y = 43;
}

if // If cart is stopped, recalculate movement vector
((am_i_doing_action() == 0) && (i <= 8)) {
print_str("Testing 17");
move_to_loc_x_y(ME,get_memory_cell(4),get_memory_cell(5));
i = i + 1;
set_memory_cell(4,x);
set_memory_cell(5,y);
}
If you guys could just help me out on this last bit, it would really help me out. I'm doing this for a school project and it's due in a few months. It's supposed to be on an epic scale.
Posts: 57 | Registered: Wednesday, July 28 2004 07:00
Post Navel Trauma ^_^
Member # 67
Profile Homepage #17
You're doing a BoA scenario for a school project?!

--------------------
Barcoorah: I even did it to a big dorset ram.

desperance.net - Don't follow this link
Posts: 1798 | Registered: Thursday, October 4 2001 07:00
Off With Their Heads
Member # 4045
Profile Homepage #18
quote:
Originally written by Venom:
They are all identical except for the coordinates.
Might I suggest memory cells usage? I haven't really followed what you're doing, but if you have ten or fewer coordinates that you're feeding each script, you only have to write one.

EDIT: And a quick skim shows me that you're already using some memory cells, although not, as far as I can tell, very many. Eh.

[ Tuesday, October 19, 2004 09:26: Message edited by: Kelandon ]

--------------------
Arancaytar: Every time you ask people to compare TM and Kel, you endanger the poor, fluffy kittens.
Smoo: Get ready to face the walls!
Ephesos: In conclusion, yarr.

Kelandon's Pink and Pretty Page!!: the authorized location for all things by me
The Archive of all released BoE scenarios ever
Posts: 7968 | Registered: Saturday, February 28 2004 08:00
Warrior
Member # 4792
Profile #19
Yes, I am doing this for school. It's actually my senior project.

And yes, I was using memory cells 4 and 5 for coordinates x and y, respectively. What exactly did you mean, Kelandon, about the memory cells? In my current format, I must double all my coordinates to loop the travel. I do have less than ten coordinates for each cart, though, not doubled.
Posts: 57 | Registered: Wednesday, July 28 2004 07:00
Off With Their Heads
Member # 4045
Profile Homepage #20
Sorry, I may just have misread you. Did you mean that you have different scripts for each cart or just one custom script that works for every cart? It sounds like the latter, in which case you can ignore my comment.

--------------------
Arancaytar: Every time you ask people to compare TM and Kel, you endanger the poor, fluffy kittens.
Smoo: Get ready to face the walls!
Ephesos: In conclusion, yarr.

Kelandon's Pink and Pretty Page!!: the authorized location for all things by me
The Archive of all released BoE scenarios ever
Posts: 7968 | Registered: Saturday, February 28 2004 08:00
Warrior
Member # 1016
Profile #21
You may be able to use roads to achieve the affect you want. For example set the cart tracks as a road and then tweak the creature script so it will only move on roads. Another idea is script the track terrains to work something like conveyor belts and depending on a variable it would move any cart object on the track forward or backward. Once the cart reaches the end of the track the variable would be switched and it would move in the oposite direction.
Posts: 141 | Registered: Saturday, April 20 2002 07:00
Warrior
Member # 4792
Profile #22
Kelandon: There are multiple scripts. I had wanted one script, but after many hours of tweaking, it seemed unfeasible. If you know something that you really think would work, I'd love to hear it.

Kennedy: I already looked into the roads option. Unfortunately, that only works for objects set on the terrain. This is terrain. The conveyor belt idea I had never thought of before. Does BoA use conveyors? I am pretty sure none of the scenarios created had any. It's been a few years, but I don't even remember if Avernum I or II had them. I never played Avernum III, and I don't know how they would fix the golem place without conveyors. Only remember Exile III style conveyors (greatest game made by SpidWeb, bar none!). If you could explain a little more, though, I'd be very interested. Can they be pushed off, though? And what happens if they are blocked? Thanks.

[ Wednesday, October 20, 2004 20:56: Message edited by: Venom ]
Posts: 57 | Registered: Wednesday, July 28 2004 07:00
...b10010b...
Member # 869
Profile Homepage #23
There aren't conveyor belts in BoA, although if you were ambitious you could try to make your own.

--------------------
The Empire Always Loses: This Time For Sure!
Posts: 9973 | Registered: Saturday, March 30 2002 08:00
Off With Their Heads
Member # 4045
Profile Homepage #24
Eh, I suppose I will have to read exactly what you're doing and how you're doing it. But if you have few enough coordinates that you're feeding the scripts, and if those coordinates are the only differences between the scripts, you can use memory cells 0-3 and 6-9 for those differences and only use one script. Just set memory cells.

I am a big proponent of memory cell usage, as it makes scripts reusable both by the designer and by others. I will actually read what you're doing and take a closer look at it to provide a more specific suggestion later.

--------------------
Arancaytar: Every time you ask people to compare TM and Kel, you endanger the poor, fluffy kittens.
Smoo: Get ready to face the walls!
Ephesos: In conclusion, yarr.

Kelandon's Pink and Pretty Page!!: the authorized location for all things by me
The Archive of all released BoE scenarios ever
Posts: 7968 | Registered: Saturday, February 28 2004 08:00

Pages