polserver/docs/maps.txt
Gabriele Tozzi 0d2237bbbf More on line endings normalization
Blame myself :P
2016-02-12 11:39:51 +01:00

820 lines
25 KiB
Text

Script & Config Changes for Editable Maps
9/10/02
Note the following changes and additions to support editable maps and course following boat functionality
(based on an 094 distro installation)
----
0.
New property for itemdesc.cfg Map{} entries: Editable, which defaults to 0
This determines if the user can plot points on the map gump. Note you can still edit the map
via the script methods listed under item 4.
1.
decodeMap.src, CreateTreasureMap:
var map := CreateItemInBackpack( who, GetObjtypeByName("map_nonedit"), 1 );
and at the end of SetTreasureCoords:
map.AppendPin(x,y);
2.
/pkg/skills/cartography/itemdesc.cfg
add:
Map 0x641E
{
Name map_nonedit
Desc Blank Map
Graphic 0x14EB
VendorSellsFor 10
VendorBuysFor 5
Editable 0
}
all the other entries add:
Editable 1
to, except for "rolledmap" and "rolledmap2"
3.
/pkg/items/treasuremap/itemdesc.cfg
add to all:
Editable 0
4.
New script methods for map obejcts:
GetPins(): returns an array of structs with .x and .y members for each pin point.
InsertPin( index, x, y ): inserts a pin with the passed x,y before the passed index. Valid range 0 to n-1
AppendPin( x, y ): appends a pin to the end of the course with the passed x,y
ErasePin( index ): erases the pin at the passed index (valid 0 to n-1), and shifts pins down.
isa(): returns true if the object is a map object
5.
Tillerman course follow functionality: in this boat.src (edit from the 094 distro)
////////////////
// boat.src
//
// control script for boats
//
// Header replaced by Racalac 9/15/02
//
// Todo/Fix: Course nav needs the "goto #" command implimented.
// Tillerman string recognition causes boat to pause
////////////////
use os;
use uo;
use util;
use boat;
use math;
include "include/eventID";
include "include/sysEvent";
include "include/myUtil";
include "include/client";
include "include/yesNo";
include "include/math";
include "util/key";
include "plankUtil";
const STATE_STATIONARY := 0;
const STATE_MOVING := 1;
const STATE_DRIFTING := 2;
const STATE_FOLLOWING_COURSE := 3;
const DELAY_DRIFTING := 15000;
const NEGONE := -1;
const ZERO := 0;
const POSONE := 1;
var state := STATE_STATIONARY;
var relative_direction;
var ms_delay_between_moves := 200;
var boat;
var tillerman;
var owner := GetObjProperty(boat.hold,"owner");
var decay := GetObjProperty(boat.tillerman, "decay");
var first_move_toward_waypoint := 1;
program autostart_boat(param)
boat := param;
if(!boat)
syslog( "[ERROR] [boat.src] Boat script running, but boat not found!" );
return;
endif
tillerman := boat.tillerman;
if(!tillerman)
syslog( "[ERROR] [boat.src] No tillerman for boat at: " +(boat.x-1) +","+ boat.y +","+ boat.z + "; destroying the boat..." );
DestroyMulti(boat);
return;
endif
EnableEvents(SYSEVENT_SPEECH, 15);
RegisterForSpeechEvents(tillerman, 15);
var nextencounter := ReadGameClock()+(RandomInt(120) + 120);
var nextsound := ReadGameClock()+5;
var driftcounter := 1;
//set_critical(1);
var x,y;
while(boat)
if(GetObjProperty(boat.hold, "#speed"))
state := STATE_MOVING;
ms_delay_between_moves := GetObjProperty(boat.hold, "#speed");
relative_direction := GetObjProperty(boat.hold, "#relativedir");
eraseobjproperty(boat.hold, "#speed");
eraseobjproperty(boat.hold, "#relativedir");
endif
decay := getobjproperty(boat.tillerman,"decay");
if((decay) and(!getobjproperty(tillerman,"nodecay")))
if(ReadGameClock() > decay)
PrintTextAbove(tillerman, "Arrrrrgh! She's going down, Captain! Abandon ship!");
sleep(4);
foreach item in EnumerateItemsInContainer( boat.hold )
DestroyItem(item);
endforeach
foreach mob in(boat.items)
DestroyItem(mob);
endforeach
foreach mob in(boat.mobiles)
MoveCharacterToLocation(mob, 1487, 1869, 0, MOVECHAR_FORCELOCATION );
SendSysMessage(mob, "Your ship, badly in need of maintenance, sinks beneath the waves!");
SendSysMessage(mob, "You awake on a distant shore...");
endforeach
if(boat.has_offline_mobiles)
foreach mob in(boat.offline_mobiles)
MoveCharacterToLocation(mob, 1487, 1869, 0, MOVECHAR_FORCELOCATION );
endforeach
endif
DestroyMulti(boat);
endif
endif
case(state)
STATE_MOVING: if(ReadGameClock() > nextsound)
PlayBoatSounds();
nextsound := ReadGameClock()+5;
endif
x := boat.x;
y := boat.y;
MoveBoatRelative(boat, relative_direction);
if(boat.x = 6 or boat.x = 5097 or boat.y = 6 or boat.y = 4089)
WorldWrap();
endif
if((x == boat.x) &&(y == boat.y))
ms_delay_between_moves := 1000;
state := STATE_DRIFTING;
PrintTextAbove(tillerman, "Aaargh! We've stopped!");
//SmackEveryone();
endif
sleepms(ms_delay_between_moves);
if(ReadGameClock() > nextencounter)
DoEncounter();
nextencounter := ReadGameClock()+120;
endif
while(events_waiting())
process_event(wait_for_event(0));
endwhile
STATE_DRIFTING: if(ReadGameClock() > nextsound)
PlayBoatSounds();
nextsound := ReadGameClock()+5;
endif
if(driftcounter > 15)
MoveBoatRelative(boat, RandomInt(8));
driftcounter := 1;
else
driftcounter := driftcounter + 1;
endif
sleepms(1000);
while(events_waiting())
process_event(wait_for_event(0));
endwhile
STATE_STATIONARY: var ev := wait_for_event(120);
if(ev)
process_event(ev);
endif
STATE_FOLLOWING_COURSE:
x := boat.x;
y := boat.y;
BoatFollowCourse(boat);
sleepms(ms_delay_between_moves);
while(events_waiting())
process_event(wait_for_event(0));
endwhile
endcase
if(ReadGameClock() > nextencounter)
checkres();
nextencounter := ReadGameClock()+120;
endif
endwhile
endprogram
function handle_speech(event)
var text := lower(event.text);
if(text["drift"] || text["raise anchor"])
ms_delay_between_moves := 1000;
state := STATE_DRIFTING;
elseif(text["forward"])
if(state = STATE_STATIONARY)
PrintTextAbove(tillerman, "The Anchor Is Down Captain!");
else
PrintTextAbove(tillerman, "Aye Aye Captain!");
state := STATE_MOVING;
if(text["left"])
relative_direction := 7;
elseif(text["right"])
relative_direction := 1;
else
relative_direction := 0;
endif
endif
elseif(text["back"])
if(state = STATE_STATIONARY)
PrintTextAbove(tillerman, "The Anchor Is Down Captain!");
else
PrintTextAbove(tillerman, "Aye Aye Captain!");
state := STATE_MOVING;
if(text["left"])
relative_direction := 5;
elseif(text["right"])
relative_direction := 3;
else
relative_direction := 4;
endif
endif
elseif(text["stop"] || text["furl sail"] || text["furl"])
PrintTextAbove(tillerman, "Aye Aye Captain!");
ms_delay_between_moves := 1000;
state := STATE_DRIFTING;
elseif(text["drop anchor"])
PrintTextAbove(tillerman, "Aye Aye Captain! Anchor Dropped.");
ms_delay_between_moves := 1000;
state := STATE_STATIONARY;
elseif(text["turn right"] || text["starboard"])
if(state = STATE_STATIONARY)
PrintTextAbove(tillerman, "The Anchor Is Down Captain!");
else
PrintTextAbove(tillerman, "Aye Aye Captain!");
TurnBoat(boat, 1);
endif
elseif(text["right"])
if(state = STATE_STATIONARY)
PrintTextAbove(tillerman, "The Anchor Is Down Captain!");
else
PrintTextAbove(tillerman, "Aye Aye Captain!");
state := STATE_MOVING;
relative_direction := 2;
endif
elseif(text["turn left"] || text["port"])
if(state = STATE_STATIONARY)
PrintTextAbove(tillerman, "The Anchor Is Down Captain!");
else
PrintTextAbove(tillerman, "Aye Aye Captain!");
TurnBoat(boat, 3);
endif
elseif(text["left"])
if(state = STATE_STATIONARY)
PrintTextAbove(tillerman, "The Anchor Is Down Captain!");
else
PrintTextAbove(tillerman, "Aye Aye Captain!");
state := STATE_MOVING;
relative_direction := 6;
endif
elseif(text["come about"] || text["turn around"])
if(state = STATE_STATIONARY)
PrintTextAbove(tillerman, "The Anchor Is Down Captain!");
else
PrintTextAbove(tillerman, "Aye Aye Captain! Coming About.");
TurnBoat(boat, 2);
sleep(1);
endif
/*NEW MAP COURSE COMMANDS*/
elseif(text["set course"])
PrintTextAbove(tillerman, "Select a map for me to follow.");
var map := Target(event.source);
if(!map.isa(POLCLASS_MAP))
PrintTextAbove(tillerman, "Are ye dense? I need a map!");
else
SetObjProperty(tillerman, "course", map.GetPins());
SetObjProperty(tillerman, "nextwaypoint", 1);
PrintTextAbove(tillerman, "Arr, course plotted.");
endif
elseif(text["clear course"])
PrintTextAbove(tillerman, "Arr, course cleared Cap'n.");
EraseObjProperty(tillerman, "course");
EraseObjProperty(tillerman, "nextwaypoint");
elseif(text["nav"])
if(state != STATE_FOLLOWING_COURSE)
PrintTextAbove(tillerman, "We are not currently following a course.");
else
PrintTextAbove(tillerman, "We are following our course.");
PrintTextAbove(tillerman, "The next waypoint is #" + GetObjProperty(tillerman,"nextwaypoint"));
endif
elseif(text["start"])
if( (GetObjProperty(tillerman,"course")==error) || (GetObjProperty(tillerman,"nextwaypoint")==error))
PrintTextAbove(tillerman,"Arr, set course first Cap'n.");
else
state := STATE_FOLLOWING_COURSE;
SetObjProperty(tillerman, "nextwaypoint", 1);
PrintTextAbove(tillerman,"Aye, sailing to first waypoint.");
endif
elseif(text["continue"])
if( (GetObjProperty(tillerman,"course")==error) || (GetObjProperty(tillerman,"nextwaypoint")==error))
PrintTextAbove(tillerman,"Arr, set course first Cap'n.");
else
state := STATE_FOLLOWING_COURSE;
PrintTextAbove(tillerman,"Aye, moving on.");
endif
endif
/*END NEW MAP COURSE COMMANDS*/
if(text["full"])
if(state != STATE_STATIONARY)
PrintTextAbove(tillerman, "Aye Aye Captain! Full Speed Ahead.");
ms_delay_between_moves := 100;
endif
elseif(text["slow"])
if(state != STATE_STATIONARY)
PrintTextAbove(tillerman, "Aye Aye Captain! ");
ms_delay_between_moves := 1000;
endif
endif
sleep(1);
if(text["one"])
if(state != STATE_STATIONARY)
MoveBoatRelative(boat, relative_direction);
state := STATE_STATIONARY;
endif
endif
endfunction
function process_event(event)
if(event.type == SYSEVENT_SPEECH)
if(CanCommandMe(event.source))
var text := lower(event.text);
if(text["drydock"])
PrintTextAbove(tillerman, "Aye Aye Captain! Docking.");
drydock(event);
sleep(1);
elseif(text["status"])
decay := GetObjProperty(boat.tillerman, "decay");
if((decay - ReadGameClock() ) > 861000 )
PrintTextAbove( tillerman, "Arrh, the ship's in excellent shape! She's a fine vessel indeed, Captain!" );
elseif((decay - ReadGameClock() ) > 604800 )
PrintTextAbove( tillerman, "She's slightly worn, Captain.");
elseif((decay - ReadGameClock() ) > 259200 )
PrintTextAbove(tillerman, "She's fairly worn, Captain.");
elseif((decay - ReadGameClock() ) > 86400 )
PrintTextAbove(tillerman, "Arrr, she's greatly worn and in dire need of repair, Captain!");
else
PrintTextAbove(tillerman, "Arrr, she's going to sink within the day if she don't get repairs soon, Captain!");
endif
else
handle_speech(event);
endif
endif
endif
endfunction
function CanCommandMe(who)
owner := GetObjProperty(boat.tillerman, "owner");
if(who.serial == owner)
return 1;
else
var packkey;
var lokid := GetObjProperty(boat.tillerman, "lockid");
foreach thing in EnumerateItemsInContainer(who.backpack)
if(GetObjProperty(thing, "lockid") = lokid)
packkey := 1;
break;
endif
endforeach
if(packkey = 1)
return 1;
else
return 0;
endif
endif
endfunction
function DoEncounter()
foreach who in ListMobilesNearLocationEx(boat.x, boat.y, GetMapInfo(boat.x, boat.y).z, 4, LISTEX_FLAG_GHOST)
if(YesNo(who,"Ressurect?"))
PlaySoundEffect(who, SFX_SPELL_RESSURECTION);
PlaySoundEffect(who, SFX_SPELL_RESSURECTION);
Resurrect(who);
endif
endforeach
var who :=(boat.mobiles);
who := who[1];
if(!who)
return;
endif
var x;
var y;
var z;
x := RandomInt(15)-5;
y := RandomInt(15)-5;
x := x + boat.x;
y := y + boat.y;
if(x > boat.x)
x := x + 5;
else
x := x - 5;
endif
if(y > boat.y)
y := y + 5;
else
y := y - 5;
endif
z := GetMapInfo(x, y).z;
if(z >= who.z)
return;
endif
var it := CreateNpcFromTemplate(getcritter(), x, y, z, 0);
if(it)
SetObjProperty(it,"killme",1);
endif
var ev := {};
ev.+type := EVID_ENTEREDAREA;
ev.+source := who;
SendEvent(it, ev);
endfunction
function checkres()
foreach who in ListMobilesNearLocationEx(boat.x, boat.y, GetMapInfo(boat.x, boat.y).z, 4, LISTEX_FLAG_GHOST)
if(who in boat.mobiles)
if(YesNo(who,"Resurrect?"))
PlaySoundEffect(who, SFX_SPELL_RESSURECTION);
PlaySoundEffect(who, SFX_SPELL_RESSURECTION);
Resurrect(who);
endif
endif
endforeach
endfunction
function getcritter()
case(RandomInt(9))
0: return "walrus";
1: return "walrus";
2: return "walrus";
3: return "walrus";
4: return "alligator";
5: return "alligator";
6: return "waterelemental";
7: return "seaserpent";
8: return "airelemental";
endcase
endfunction
function drydock(event)
if(GetObjProperty(event.source, "#DryDocking"))
SendSysMessage(event.source, "You are already doing something else.");
return;
endif
SetObjProperty(event.source, "#DryDocking", 1);
EraseObjProperty(event.source, "#DryDocking");
var text := lower(event.text);
if(!text["drydock"])
EraseObjProperty(event.source, "#DryDocking");
return;
endif
var me := event.source;
var items := boat.items;
if(len(items) > 0)
PrintTextAbovePrivate(boat.tillerman, "You cannot drydock the boat while items are on deck.", me);
EraseObjProperty(me, "#DryDocking");
return;
endif
items := EnumerateItemsInContainer(boat.hold);
if(len(items) > 0)
PrintTextAbovePrivate(boat.tillerman, "You cannot drydock the boat while items are in the hold.", me);
EraseObjProperty(me, "#DryDocking");
return;
endif
if(CanDockMe(boat, me))
if(!YesNo(me,"Drydock?"))
EraseObjProperty(me, "#DryDocking");
return;
endif
var shiptype;
case(boat.objtype)
0x6040: shiptype := 0x6027;
0x6041: shiptype := 0x6028;
0x6042: shiptype := 0x6029;
0x6043: shiptype := 0x602a;
0x6044: shiptype := 0x602b;
0x6045: shiptype := 0x602c;
endcase
if(!shiptype)
SendSysMessage(me, "Your boat seems to be malfunctioning. Please page a GM.");
return;
endif
var newboat := CreateItemInContainer(me.backpack, shiptype, 1);
var key := FindKey(me, boat.tillerman);
if(key)
DestroyItem(key);
endif
if(!newboat)
SendSysMessage(me,"Could not create boat deed in your backpack!");
EraseObjProperty(me, "#DryDocking");
return;
endif
if(ReserveItem(newboat))
newboat.graphic := 0x14f3;
if(!boat.tillerman.name)
newboat.name := "a toy boat";
else
newboat.name := boat.tillerman.name;
endif
if(!DestroyBoat(boat))
DestroyItem(newboat);
endif
else
DestroyItem(newboat);
endif
endif
EraseObjProperty(me, "#DryDocking");
endfunction
function DestroyBoat(who)
var res := DestroyMulti(boat);
if(!res)
return 0;
endif
return 1;
endfunction
function SmackEveryone()
foreach mob in(boat.mobiles)
ApplyDamage(mob,RandomInt(10));
PerformAction(mob,0x14);
PlaySoundEffect(mob,0x110);
endforeach
endfunction
function PlayBoatSounds()
var who := RandomInt(len(boat.mobiles)+1);
var mobs :=(boat.mobiles);
if(RandomInt(2) == 1)
PlaySoundEffect(mobs[who],0x13);
else
PlaySoundEffect(mobs[who],0x14);
endif
endfunction
function WorldWrap()
var newx := boat.x;
var newy := boat.y;
if(boat.y <= 6)
newy := 4088;
elseif(boat.y >= 4089)
newy := 6;
endif
if(boat.x <= 6)
newx := 5096;
elseif(boat.x >= 5097)
newx := 6;
endif
var lockid := GetObjProperty(boat.hold, "lockid");
var owner := GetObjProperty(boat.hold, "owner");
var shiptype := boat.objtype;
var shipfacing, created;
case(tillerman.graphic)
0x3e4e: shipfacing := CRMULTI_FACING_NORTH;
0x3e55: shipfacing := CRMULTI_FACING_EAST;
0x3e4b: shipfacing := CRMULTI_FACING_SOUTH;
0x3e50: shipfacing := CRMULTI_FACING_WEST;
default: shipfacing := "Error!";
endcase
if(shipfacing="Error!")
syslog( "[ERROR] [boat.src] Couldn't tell which way the ship was facing for the worldwrap!");
endif
created := CreateMultiAtLocation( newx, newy, -5, shiptype, shipfacing);
if(!created)
syslog( "[ERROR] [boat.src] New ship couldn't be created for worldwrap!");
return;
endif
var oldshiphold := boat.hold;
var newshiphold := created.hold;
foreach item in EnumerateItemsInContainer( oldshiphold )
if(item.container = oldshiphold)
MoveItemToContainer(item, newshiphold);
endif
endforeach
foreach item in EnumerateItemsInContainer( oldshiphold )
MoveItemToContainer(item, newshiphold);
endforeach
foreach mob in(boat.mobiles)
MoveCharacterToLocation(mob,(mob.x-boat.x)+created.x,(mob.y-boat.y)+created.y, -2, MOVECHAR_FORCELOCATION );
endforeach
if(boat.has_offline_mobiles)
foreach mob in(boat.offline_mobiles)
MoveCharacterToLocation(mob,(mob.x-boat.x)+created.x,(mob.y-boat.y)+created.y, -2, MOVECHAR_FORCELOCATION );
endforeach
endif
foreach mob in(boat.items)
MoveitemToLocation(mob,(mob.x-boat.x)+created.x,(mob.y-boat.y)+created.y, -2,0 );
endforeach
var newtillerman := created.tillerman;
newtillerman.name := tillerman.name;
SetObjProperty( created.starboardplank, "lockid", lockid);
SetObjProperty( created.portplank, "lockid", lockid);
SetObjProperty( created.ship.starboardplank, "owner", owner );
SetObjProperty( created.ship.portplank, "owner", owner );
SetObjProperty( created.ship.starboardplank, "tillermanid", newtillerman.serial );
SetObjProperty( created.ship.portplank, "tillermanid", newtillerman.serial );
SetObjProperty( created.hold, "lockid", lockid);
SetObjProperty( created.hold, "owner", owner);
SetObjProperty( created.tillerman, "owner", owner);
SetObjProperty( created.tillerman, "shipserial", created.serial);
SetObjProperty( created.tillerman, "lockid", lockid);
SetObjProperty( created.tillerman, "decay", decay);
if(boat.starboardplank.locked = 1)
created.starboardplank.locked := 1;
endif
if(boat.portplank.locked = 1)
created.portplank.locked := 1;
endif
if(boat.hold.locked = 1)
created.hold.locked := 1;
endif
SetObjProperty( created.hold, "#relativedir", relative_direction);
SetObjProperty( created.hold, "#speed", ms_delay_between_moves);
created.tillerman.usescript := ":boat:tillerman";
if(!DestroyMulti(boat))
DestroyItem(boat.tillerman);
syslog( "[ERROR] [boat.src] Old ship at " +(boat.x-1) +","+ boat.y +","+ boat.z + " couldn't be destroyed during worldwrap!");
endif
endfunction
function CanDockMe(boat, who)
if(GetObjProperty(boat.hold,"owner") == who.serial)
return 1;
else
var packkey;
var lokid := GetObjProperty(boat.tillerman, "lockid");
foreach thing in EnumerateItemsInContainer(who.backpack)
if(GetObjProperty(thing, "lockid") = lokid)
packkey := 1;
break;
endif
endforeach
if(packkey = 1)
return 1;
else
return 0;
endif
endif
endfunction
/*NEW MAP COURSE FUNCTIONS*/
//follows the current course
function BoatFollowCourse(boat)
var startx, starty, destx, desty;
var course, nextwaypoint;
var newpoint, newfacing, prevfacing;
course := GetObjProperty(boat.tillerman,"course");
nextwaypoint := GetObjProperty(boat.tillerman,"nextwaypoint");
startx := boat.x;
starty := boat.y;
prevfacing := boat.facing;
if( (course==error) || (nextwaypoint==error))
return;
endif
destx := course[nextwaypoint].x;
desty := course[nextwaypoint].y;
newpoint := lineBresenham(startx,starty,destx,desty);
newfacing := GetNewFacing(startx,starty,newpoint[1],newpoint[2]);
if(newfacing == error) //reached waypoint/end
nextwaypoint := nextwaypoint + 1;
first_move_toward_waypoint := 1; //so we turn toward next waypoint (includes next course follow if we're done with this one)
if(nextwaypoint > course.size()) //done
state := STATE_DRIFTING;
PrintTextAbove(boat.tillerman,"Arr, we've reached our destination.");
return;
else
SetObjProperty(boat.tillerman,"nextwaypoint",nextwaypoint);
endif
else
if(first_move_toward_waypoint == 1)
if( prevfacing != newfacing )
TurnBoat(boat,Cint(DetermineTurnCode(boat,newfacing)) );
endif
first_move_toward_waypoint := 0;
endif
MoveBoat(boat,newfacing);
if((startx == boat.x) &&(starty == boat.y)) //we didn't move. must be blocked
state := STATE_DRIFTING;
PrintTextAbove(tillerman, "Aaargh! We've stopped!");
endif
endif
endfunction
//convert facing 0-7 to turn code 0-3
function DetermineTurnCode( boat, desired )
var current := CInt(boat.facing / 2);
desired := CInt(desired / 2);
if ( desired < current )
desired := desired + 4;
endif
return (desired - current);
endfunction
//returns the direction (x1,y1) lies from (x0,y0) in the range 0-7.
// returns error if the 2 points are equal.
function GetNewFacing(x0,y0,x1,y1)
var dx, dy;
var facing;
dx := x1 - x0;
dy := y1 - y0;
case(dx)
NEGONE:
case(dy)
NEGONE: facing := 7;
ZERO: facing := 6;
POSONE: facing := 5;
default: facing := error;
endcase
ZERO:
case(dy)
NEGONE: facing := 0;
ZERO: facing := error;
POSONE: facing := 4;
default: facing := error;
endcase
POSONE:
case(dy)
NEGONE: facing := 1;
ZERO: facing := 2;
POSONE: facing := 3;
default: facing := error;
endcase
default: facing := error;
endcase
return facing;
endfunction
//Bresenham's line drawing algorithm. determines a line between two waypoints.
function lineBresenham(x0, y0, x1, y1)
var dy;
dy := y1 - y0;
var dx;
dx := x1 - x0;
var stepx, stepy;
if (dy < 0)
dy := -dy;
stepy := -1;
else
stepy := 1;
endif
if (dx < 0)
dx := -dx;
stepx := -1;
else
stepx := 1;
endif
dy := 2*dy;
dx := 2*dx;
if (dx > dy)
var fraction;
fraction := 2*dy - dx;
while (x0 != x1)
if (fraction >= 0)
y0 := y0 + stepy;
fraction := fraction - dx;
endif
x0 := x0 + stepx;
fraction := fraction + dy;
return {x0, y0};
endwhile
else
var fraction;
fraction := 2*dx - dy;
while (y0 != y1)
if (fraction >= 0)
x0 := x0 + stepx;
fraction := fraction - dy;
endif
y0 := y0 + stepy;
fraction := fraction + dx;
return {x0, y0};
endwhile
endif
endfunction
/*END NEW MAP COURSE FUNCTIONS*/