Client Navigation Generator (#6023)
Creates navigation files for the client.
This commit is contained in:
parent
b1b371f4b8
commit
c751ca6b74
3
.gitignore
vendored
3
.gitignore
vendored
@ -144,3 +144,6 @@ Thumbs.db
|
||||
|
||||
# CMakeFiles
|
||||
/CMakeFiles/
|
||||
|
||||
# generated files
|
||||
generated
|
||||
|
@ -60,6 +60,7 @@ libconfig:
|
||||
|
||||
tools:
|
||||
@$(MAKE) -C src/tool
|
||||
@$(MAKE) -C src/map tools
|
||||
|
||||
rapidyaml:
|
||||
@$(MAKE) -C 3rdparty/rapidyaml
|
||||
|
@ -978,6 +978,11 @@ Only the special labels which are not associated with any script command are
|
||||
listed here. There are other kinds of labels which may be triggered in a similar
|
||||
manner, but they are described with their associated commands.
|
||||
|
||||
OnNaviGenerate:
|
||||
|
||||
This special label triggers when running the map-server-generator binary. It is used
|
||||
in combination with 'naviregisterwarp' to register extra warps for an npc.
|
||||
|
||||
On<label name>:
|
||||
|
||||
These special labels are used with Mob scripts mostly, and script commands
|
||||
@ -9446,6 +9451,20 @@ with the given character id.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*naviregisterwarp("<Name of Link>", "<dest_map>", <dest_x>, <dest_y>)
|
||||
|
||||
Only useful when using the map-server-generator. Registers an extra warp from this
|
||||
npc to the destination map/x/y for the generated client files.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*navihide
|
||||
|
||||
Only useful when using the map-server-generator. Hides this npc and all links from
|
||||
this npc in the navigation generation.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
========================
|
||||
|7.- Instance commands.|
|
||||
========================
|
||||
|
@ -526,6 +526,707 @@ S9: Restrict("RE");
|
||||
Go("paramk",97,17);
|
||||
S10: Go("turbo_room",99,114);
|
||||
|
||||
OnNaviGenerate:
|
||||
|
||||
// for non-prontera warpers, just give it warp to prontera
|
||||
// this cuts down the number of links considerably
|
||||
if (strnpcinfo(4) != "prontera") {
|
||||
naviregisterwarp("Warper > Prontera", "prontera", 155, 183);
|
||||
end;
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Prontera", "prontera", 155, 183);
|
||||
naviregisterwarp("Warper > Alberta", "alberta", 28, 234);
|
||||
naviregisterwarp("Warper > Al De Baran", "aldebaran", 140, 131);
|
||||
naviregisterwarp("Warper > Amatsu", "amatsu", 198, 84);
|
||||
naviregisterwarp("Warper > Ayothaya", "ayothaya", 208, 166);
|
||||
naviregisterwarp("Warper > Einbech", "einbech",63,35);
|
||||
naviregisterwarp("Warper > Einbroch", "einbroch",64,200);
|
||||
naviregisterwarp("Warper > Geffen", "geffen",119,59);
|
||||
naviregisterwarp("Warper > Hugel", "hugel",96,145);
|
||||
naviregisterwarp("Warper > Izlude", "izlude",128,(checkre(3)?146:114));
|
||||
naviregisterwarp("Warper > Jawaii", "jawaii",251,132);
|
||||
naviregisterwarp("Warper > Juno", "yuno",157,51);
|
||||
naviregisterwarp("Warper > Kunlun", "gonryun",160,120);
|
||||
naviregisterwarp("Warper > Lighthalzen", "lighthalzen",158,92);
|
||||
naviregisterwarp("Warper > Luoyang", "louyang",217,100);
|
||||
naviregisterwarp("Warper > Lutie", "xmas",147,134);
|
||||
naviregisterwarp("Warper > Manuk", "manuk",282,138);
|
||||
naviregisterwarp("Warper > Midgarts Expedition Camp", "mid_camp",210,288);
|
||||
naviregisterwarp("Warper > Morocc", "morocc",156,93);
|
||||
naviregisterwarp("Warper > Moscovia", "moscovia",223,184);
|
||||
naviregisterwarp("Warper > Nameless Island", "nameless_n",256,215);
|
||||
naviregisterwarp("Warper > Niflheim", "niflheim",202,174);
|
||||
naviregisterwarp("Warper > Payon", "payon",179,100);
|
||||
naviregisterwarp("Warper > Rachel", "rachel",130,110);
|
||||
naviregisterwarp("Warper > Splendide", "splendide",201,147);
|
||||
naviregisterwarp("Warper > Thor Camp", "thor_camp",246,68);
|
||||
naviregisterwarp("Warper > Umbala", "umbala",97,153);
|
||||
naviregisterwarp("Warper > Veins", "veins",216,123);
|
||||
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Brasilis", "brasilis", 196, 217);
|
||||
naviregisterwarp("Warper > Dewata", "dewata",200,180);
|
||||
naviregisterwarp("Warper > Eclage", "ecl_in01",48,53);
|
||||
naviregisterwarp("Warper > El Dicastes", "dicastes01",198,187);
|
||||
naviregisterwarp("Warper > Lasagna", "lasagna",193,182);
|
||||
naviregisterwarp("Warper > Malangdo", "malangdo",140,114);
|
||||
naviregisterwarp("Warper > Malaya", "malaya",231,200);
|
||||
naviregisterwarp("Warper > Mora", "mora",55,146);
|
||||
}
|
||||
|
||||
// fields
|
||||
naviregisterwarp("Warper > Amatsu Field", "ama_fild01", 190, 197);
|
||||
naviregisterwarp("Warper > Ayothaya Field", "ayo_fild01", 173, 134);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Ayothaya Field", "ayo_fild02", 212, 150);
|
||||
}
|
||||
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Bifrost Field", "bif_fild01", 193, 220);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Bifrost Field", "bif_fild02", 220, 187);
|
||||
}
|
||||
naviregisterwarp("Warper > Brasilis Field", "bra_fild01", 74, 32);
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Comodo Field", "cmd_fild01", 180, 178);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Comodo Field", "cmd_fild02", 231, 160);
|
||||
naviregisterwarp("Warper > Comodo Field", "cmd_fild03", 191, 172);
|
||||
naviregisterwarp("Warper > Comodo Field", "cmd_fild04", 228, 194);
|
||||
if (!checkre(0)) {
|
||||
naviregisterwarp("Warper > Comodo Field", "cmd_fild05", 224, 203);
|
||||
}
|
||||
naviregisterwarp("Warper > Comodo Field", "cmd_fild06", 190, 223);
|
||||
naviregisterwarp("Warper > Comodo Field", "cmd_fild07", 234, 177);
|
||||
naviregisterwarp("Warper > Comodo Field", "cmd_fild08", 194, 175);
|
||||
naviregisterwarp("Warper > Comodo Field", "cmd_fild09", 172, 172);
|
||||
}
|
||||
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Dewata Field", "dew_fild01", 371, 212);
|
||||
naviregisterwarp("Warper > Eclage Field", "ecl_fild01", 97, 314);
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Einbroch Field", "ein_fild01", 142, 225);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Einbroch Field", "ein_fild03", 187, 228);
|
||||
naviregisterwarp("Warper > Einbroch Field", "ein_fild04", 185, 173);
|
||||
naviregisterwarp("Warper > Einbroch Field", "ein_fild05", 216, 173);
|
||||
naviregisterwarp("Warper > Einbroch Field", "ein_fild06", 195, 148);
|
||||
naviregisterwarp("Warper > Einbroch Field", "ein_fild07", 272, 220);
|
||||
naviregisterwarp("Warper > Einbroch Field", "ein_fild08", 173, 214);
|
||||
naviregisterwarp("Warper > Einbroch Field", "ein_fild09", 207, 174);
|
||||
if (!checkre(0)) {
|
||||
naviregisterwarp("Warper > Einbroch Field", "ein_fild02", 182, 141);
|
||||
naviregisterwarp("Warper > Einbroch Field", "ein_fild10", 196, 200);
|
||||
}
|
||||
}
|
||||
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > El Dicastes Field", "dic_fild01", 143, 132);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > El Dicastes Field", "dic_fild02", 143, 217);
|
||||
}
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Geffen Field 0", "gef_fild00", 46, 199);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Geffen Field 1", "gef_fild01", 213, 204);
|
||||
naviregisterwarp("Warper > Geffen Field 2", "gef_fild02", 195, 212);
|
||||
naviregisterwarp("Warper > Geffen Field 3", "gef_fild03", 257, 192);
|
||||
naviregisterwarp("Warper > Geffen Field 4", "gef_fild04", 188, 171);
|
||||
naviregisterwarp("Warper > Geffen Field 5", "gef_fild05", 166, 263);
|
||||
naviregisterwarp("Warper > Geffen Field 6", "gef_fild06", 248, 158);
|
||||
naviregisterwarp("Warper > Geffen Field 7", "gef_fild07", 195, 191);
|
||||
naviregisterwarp("Warper > Geffen Field 8", "gef_fild08", 186, 183);
|
||||
naviregisterwarp("Warper > Geffen Field 9", "gef_fild09", 221, 117);
|
||||
naviregisterwarp("Warper > Geffen Field 10", "gef_fild10", 178, 218);
|
||||
naviregisterwarp("Warper > Geffen Field 11", "gef_fild11", 136, 328);
|
||||
naviregisterwarp("Warper > Geffen Field 13", "gef_fild13", 235, 235);
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Geffen Field 12", "gef_fild12", 240, 181);
|
||||
naviregisterwarp("Warper > Geffen Field 14", "gef_fild14", 211, 185);
|
||||
}
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Kunlun Field 1", "gon_fild01", 220, 227);
|
||||
|
||||
naviregisterwarp("Warper > Hugel Field 1", "hu_fild01", 268, 101);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Hugel Field 2", "hu_fild02", 222, 193);
|
||||
naviregisterwarp("Warper > Hugel Field 4", "hu_fild04", 252, 189);
|
||||
naviregisterwarp("Warper > Hugel Field 5", "hu_fild05", 196, 106);
|
||||
naviregisterwarp("Warper > Hugel Field 6", "hu_fild06", 216, 220);
|
||||
if (!checkre(0)) {
|
||||
naviregisterwarp("Warper > Hugel Field 3", "hu_fild03", 232, 185);
|
||||
naviregisterwarp("Warper > Hugel Field 7", "hu_fild07", 227, 197);
|
||||
}
|
||||
}
|
||||
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Lasagna Field 1", "lasa_fild01", 344, 371);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Lasagna Field 2", "lasa_fild02", 20, 98);
|
||||
}
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Lighthalzen Field 1", "lhz_fild01", 240, 179);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Lighthalzen Field 2", "lhz_fild02", 185, 235);
|
||||
naviregisterwarp("Warper > Lighthalzen Field 3", "lhz_fild03", 240, 226);
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Luoyang Field 1", "lou_fild01", 229, 187);
|
||||
|
||||
naviregisterwarp("Warper > Lutie Field 1", "xmas_fild01", 115, 145);
|
||||
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Malaya Field 1", "ma_fild01", 40, 272);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Malaya Field 2", "ma_fild02", 207, 180);
|
||||
}
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Manuk Field 1", "man_fild01", 35, 236);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Manuk Field 2", "man_fild02", 35, 262);
|
||||
naviregisterwarp("Warper > Manuk Field 3", "man_fild03", 84, 365);
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Mjolnir Field 1", "mjolnir_01", 204, 120);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Mjolnir Field 2", "mjolnir_02", 175, 193);
|
||||
naviregisterwarp("Warper > Mjolnir Field 3", "mjolnir_03", 208, 213);
|
||||
naviregisterwarp("Warper > Mjolnir Field 4", "mjolnir_04", 179, 180);
|
||||
naviregisterwarp("Warper > Mjolnir Field 5", "mjolnir_05", 181, 240);
|
||||
naviregisterwarp("Warper > Mjolnir Field 6", "mjolnir_06", 195, 270);
|
||||
naviregisterwarp("Warper > Mjolnir Field 7", "mjolnir_07", 235, 202);
|
||||
naviregisterwarp("Warper > Mjolnir Field 8", "mjolnir_08", 188, 215);
|
||||
naviregisterwarp("Warper > Mjolnir Field 9", "mjolnir_09", 205, 144);
|
||||
naviregisterwarp("Warper > Mjolnir Field 10", "mjolnir_10", 245, 223);
|
||||
naviregisterwarp("Warper > Mjolnir Field 11", "mjolnir_11", 180, 206);
|
||||
naviregisterwarp("Warper > Mjolnir Field 12", "mjolnir_12", 196, 208);
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Moscovia Field 1", "mosk_fild01", 82, 104);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Moscovia Field 2", "mosk_fild02", 131, 147);
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Niflheim Field 1", "nif_fild01", 215, 229);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warer > Niflheim Field 2", "nif_fild02", 167, 234);
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Payon Forest 1", "pay_fild01", 158, 206);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Payon Forest 2", "pay_fild02", 151, 219);
|
||||
naviregisterwarp("Warper > Payon Forest 3", "pay_fild03", 205, 148);
|
||||
naviregisterwarp("Warper > Payon Forest 4", "pay_fild04", 186, 247);
|
||||
naviregisterwarp("Warper > Payon Forest 6", "pay_fild06", 193, 235);
|
||||
naviregisterwarp("Warper > Payon Forest 7", "pay_fild07", 200, 177);
|
||||
naviregisterwarp("Warper > Payon Forest 8", "pay_fild08", 137, 189);
|
||||
naviregisterwarp("Warper > Payon Forest 9", "pay_fild09", 201, 224);
|
||||
naviregisterwarp("Warper > Payon Forest 10", "pay_fild10", 160, 205);
|
||||
if (!checkre(0)) {
|
||||
naviregisterwarp("Warper > Payon Forest 5", "pay_fild05", 134, 204);
|
||||
naviregisterwarp("Warper > Payon Forest 11", "pay_fild11", 194, 150);
|
||||
}
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Prontera Field 0", "prt_fild00", 208, 227);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Prontera Field 1", "prt_fild01", 190, 206);
|
||||
naviregisterwarp("Warper > Prontera Field 2", "prt_fild02", 240, 206);
|
||||
naviregisterwarp("Warper > Prontera Field 3", "prt_fild03", 190, 143);
|
||||
naviregisterwarp("Warper > Prontera Field 4", "prt_fild04", 307, 252);
|
||||
naviregisterwarp("Warper > Prontera Field 5", "prt_fild05", 239, 213);
|
||||
naviregisterwarp("Warper > Prontera Field 6", "prt_fild06", 185, 188);
|
||||
naviregisterwarp("Warper > Prontera Field 7", "prt_fild07", 193, 194);
|
||||
naviregisterwarp("Warper > Prontera Field 8", "prt_fild08", 187, 218);
|
||||
naviregisterwarp("Warper > Prontera Field 9", "prt_fild09", 210, 183);
|
||||
naviregisterwarp("Warper > Prontera Field 10", "prt_fild10", 195, 149);
|
||||
naviregisterwarp("Warper > Prontera Field 11", "prt_fild11", 198, 164);
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Rachel Field 1", "ra_fild01", 192, 162);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Rachel Field 3", "ra_fild03", 202, 206);
|
||||
naviregisterwarp("Warper > Rachel Field 4", "ra_fild04", 202, 208);
|
||||
naviregisterwarp("Warper > Rachel Field 5", "ra_fild05", 225, 202);
|
||||
naviregisterwarp("Warper > Rachel Field 6", "ra_fild06", 202, 214);
|
||||
naviregisterwarp("Warper > Rachel Field 8", "ra_fild08", 217, 201);
|
||||
naviregisterwarp("Warper > Rachel Field 12", "ra_fild12", 175, 200);
|
||||
|
||||
if (!checkre(0)) {
|
||||
naviregisterwarp("Warper > Rachel Field 2", "ra_fild02", 235, 166);
|
||||
naviregisterwarp("Warper > Rachel Field 7", "ra_fild07", 263, 196);
|
||||
naviregisterwarp("Warper > Rachel Field 9", "ra_fild09", 87, 121);
|
||||
naviregisterwarp("Warper > Rachel Field 10", "ra_fild10", 277, 181);
|
||||
naviregisterwarp("Warper > Rachel Field 11", "ra_fild11", 221, 185);
|
||||
naviregisterwarp("Warper > Rachel Field 13", "ra_fild13", 174, 197);
|
||||
}
|
||||
}
|
||||
|
||||
if (.Satan_Morocc) {
|
||||
naviregisterwarp("Warper > Sograt Desert 1", "moc_fild01", 219, 205);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Sograt Desert 2", "moc_fild02", 177, 206);
|
||||
naviregisterwarp("Warper > Sograt Desert 3", "moc_fild03", 194, 182);
|
||||
naviregisterwarp("Warper > Sograt Desert 7", "moc_fild07", 224, 170);
|
||||
naviregisterwarp("Warper > Sograt Desert 11", "moc_fild11", 198, 216);
|
||||
naviregisterwarp("Warper > Sograt Desert 12", "moc_fild12", 156, 187);
|
||||
naviregisterwarp("Warper > Sograt Desert 13", "moc_fild13", 185, 263);
|
||||
naviregisterwarp("Warper > Sograt Desert 16", "moc_fild16", 206, 228);
|
||||
naviregisterwarp("Warper > Sograt Desert 17", "moc_fild17", 208, 238);
|
||||
naviregisterwarp("Warper > Sograt Desert 18", "moc_fild18", 209, 223);
|
||||
naviregisterwarp("Warper > Sograt Desert 19", "moc_fild19", 85, 97);
|
||||
naviregisterwarp("Warper > Sograt Desert 20", "moc_fild20", 207, 202);
|
||||
naviregisterwarp("Warper > Sograt Desert 21", "moc_fild21", 31, 195);
|
||||
naviregisterwarp("Warper > Sograt Desert 22", "moc_fild22", 38, 195);
|
||||
}
|
||||
} else {
|
||||
naviregisterwarp("Warper > Sograt Desert 1", "moc_fild01", 219, 205);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Sograt Desert 2", "moc_fild02", 177, 206);
|
||||
naviregisterwarp("Warper > Sograt Desert 3", "moc_fild03", 194, 182);
|
||||
naviregisterwarp("Warper > Sograt Desert 4", "moc_fild04", 146, 297);
|
||||
naviregisterwarp("Warper > Sograt Desert 5", "moc_fild05", 204, 197);
|
||||
naviregisterwarp("Warper > Sograt Desert 6", "moc_fild06", 275, 302);
|
||||
naviregisterwarp("Warper > Sograt Desert 7", "moc_fild07", 224, 170);
|
||||
naviregisterwarp("Warper > Sograt Desert 8", "moc_fild08", 139, 123);
|
||||
naviregisterwarp("Warper > Sograt Desert 9", "moc_fild09", 101, 110);
|
||||
naviregisterwarp("Warper > Sograt Desert 10", "moc_fild10", 341, 39);
|
||||
naviregisterwarp("Warper > Sograt Desert 11", "moc_fild11", 198, 216);
|
||||
naviregisterwarp("Warper > Sograt Desert 12", "moc_fild12", 156, 187);
|
||||
naviregisterwarp("Warper > Sograt Desert 13", "moc_fild13", 185, 263);
|
||||
naviregisterwarp("Warper > Sograt Desert 14", "moc_fild14", 223, 222);
|
||||
naviregisterwarp("Warper > Sograt Desert 15", "moc_fild15", 170, 257);
|
||||
naviregisterwarp("Warper > Sograt Desert 16", "moc_fild16", 206, 228);
|
||||
naviregisterwarp("Warper > Sograt Desert 17", "moc_fild17", 208, 238);
|
||||
naviregisterwarp("Warper > Sograt Desert 18", "moc_fild18", 209, 223);
|
||||
naviregisterwarp("Warper > Sograt Desert 19", "moc_fild19", 85, 97);
|
||||
}
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Splendide Field 1", "spl_fild01", 175, 186);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Splendide Field 2", "spl_fild02", 236, 184);
|
||||
naviregisterwarp("Warper > Splendide Field 3", "spl_fild03", 188, 204);
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Umbala Field 1", "um_fild01", 217, 206);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Umbala Field 2", "um_fild02", 223, 221);
|
||||
naviregisterwarp("Warper > Umbala Field 3", "um_fild03", 237, 215);
|
||||
naviregisterwarp("Warper > Umbala Field 4", "um_fild04", 202, 197);
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Veins Field 1", "ve_fild01", 186, 175);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Veins Field 2", "ve_fild02", 196, 370);
|
||||
naviregisterwarp("Warper > Veins Field 3", "ve_fild03", 222, 45);
|
||||
naviregisterwarp("Warper > Veins Field 4", "ve_fild04", 51, 250);
|
||||
naviregisterwarp("Warper > Veins Field 6", "ve_fild06", 150, 223);
|
||||
naviregisterwarp("Warper > Veins Field 7", "ve_fild07", 149, 307);
|
||||
if (!checkre(0)) {
|
||||
naviregisterwarp("Warper > Veins Field 5", "ve_fild05", 202, 324);
|
||||
}
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Juno Field 1", "yuno_fild01", 189, 224);
|
||||
if (!.OnlyFirstFld) {
|
||||
naviregisterwarp("Warper > Juno Field 2", "yuno_fild02", 192, 207);
|
||||
naviregisterwarp("Warper > Juno Field 3", "yuno_fild03", 221, 157);
|
||||
naviregisterwarp("Warper > Juno Field 4", "yuno_fild04", 226, 199);
|
||||
naviregisterwarp("Warper > Juno Field 6", "yuno_fild06", 187, 232);
|
||||
naviregisterwarp("Warper > Juno Field 7", "yuno_fild07", 231, 174);
|
||||
naviregisterwarp("Warper > Juno Field 8", "yuno_fild08", 196, 203);
|
||||
naviregisterwarp("Warper > Juno Field 9", "yuno_fild09", 183, 214);
|
||||
naviregisterwarp("Warper > Juno Field 11", "yuno_fild11", 195, 226);
|
||||
naviregisterwarp("Warper > Juno Field 12", "yuno_fild12", 210, 304);
|
||||
if (!checkre(0)) {
|
||||
naviregisterwarp("Warper > Juno Field 5", "yuno_fild05", 223, 177);
|
||||
naviregisterwarp("Warper > Juno Field 10", "yuno_fild10", 200, 124);
|
||||
}
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Abyss Lakes 1", "abyss_01", 261, 272);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Abyss Lakes 2", "abyss_02", 275, 270);
|
||||
naviregisterwarp("Warper > Abyss Lakes 3", "abyss_03", 116, 27);
|
||||
}
|
||||
naviregisterwarp("Warper > Amatsu Dungeon 1", "ama_dun01", 228, 11);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Amatsu Dungeon 2", "ama_dun02", 34, 41);
|
||||
naviregisterwarp("Warper > Amatsu Dungeon 3", "ama_dun03", 119, 14);
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Anthell 1", "anthell01", 35, 262);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Anthell 2", "anthell02", 168, 170);
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Ancient Shrine Maze", "ayo_dun01", 275, 19);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Inside Ancient Shrine", "ayo_dun02", 24, 26);
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Beach Dungeon 1", "beach_dun", 266, 67);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Beach Dungeon 2", "beach_dun2", 255, 244);
|
||||
naviregisterwarp("Warper > Beach Dungeon 3", "beach_dun3", 23, 260);
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Bio Lab 1", "lhz_dun01", 150, 288);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Bio Lab 2", "lhz_dun02", 150, 18);
|
||||
naviregisterwarp("Warper > Bio Lab 3", "lhz_dun03", 140, 134);
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Bio Lab 4", "lhz_dun04", 244, 52);
|
||||
}
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Brasilis Dungeon 1", "bra_dun01", 87, 47);
|
||||
if (!.OnlyFirstDun) {
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Brasilis Dungeon 2", "bra_dun02", 262, 262);
|
||||
}
|
||||
}
|
||||
|
||||
naviregisterwarp("Warper > Byalan Dungeon 1", "iz_dun00", 168, 168);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Byalan Dungeon 2", "iz_dun01", 253, 252);
|
||||
naviregisterwarp("Warper > Byalan Dungeon 3", "iz_dun02", 236, 204);
|
||||
naviregisterwarp("Warper > Byalan Dungeon 4", "iz_dun03", 32, 63);
|
||||
naviregisterwarp("Warper > Byalan Dungeon 5", "iz_dun04", 26, 27);
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Byalan Dungeon 6", "iz_dun05", 141, 187);
|
||||
}
|
||||
}
|
||||
naviregisterwarp("Warper > Clock Tower 1", "c_tower1", 199, 159);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Clock Tower 2", "c_tower2", 148, 283);
|
||||
naviregisterwarp("Warper > Clock Tower 3", "c_tower3", 65, 147);
|
||||
naviregisterwarp("Warper > Clock Tower 4", "c_tower4", 56, 155);
|
||||
naviregisterwarp("Warper > Basement 1", "alde_dun01", 297, 25);
|
||||
naviregisterwarp("Warper > Basement 2", "alde_dun02", 127, 169);
|
||||
naviregisterwarp("Warper > Basement 3", "alde_dun03", 277, 178);
|
||||
naviregisterwarp("Warper > Basement 4", "alde_dun04", 268, 74);
|
||||
}
|
||||
naviregisterwarp("Warper > Coal Mines 1", "mjo_dun01", 52, 17);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Coal Mines 2", "mjo_dun02", 381, 343);
|
||||
naviregisterwarp("Warper > Coal Mines 3", "mjo_dun03", 302, 262);
|
||||
}
|
||||
naviregisterwarp("Warper > Culvert 1", "prt_sewb1", 131, 247);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Culvert 2", "prt_sewb2", 19, 19);
|
||||
naviregisterwarp("Warper > Culvert 3", "prt_sewb3", 180, 169);
|
||||
naviregisterwarp("Warper > Culvert 4", "prt_sewb4", 100, 92);
|
||||
}
|
||||
naviregisterwarp("Warper > Cursed Abbey 1", "abbey01", 51, 14);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Cursed Abbey 2", "abbey02", 150, 11);
|
||||
naviregisterwarp("Warper > Cursed Abbey 3", "abbey03", 120, 10);
|
||||
}
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Dewata Dungeon 1", "dew_dun01", 285, 160);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Dewata Dungeon 2", "dew_dun02", 299, 29);
|
||||
}
|
||||
}
|
||||
naviregisterwarp("Warper > Einbroch Dungeon 1", "ein_dun01", 22, 14);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Einbroch Dungeon 2", "ein_dun02", 292, 290);
|
||||
}
|
||||
naviregisterwarp("Warper > Gefenia 1", "gefenia01", 40, 103);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Gefenia 2", "gefenia02", 203, 34);
|
||||
naviregisterwarp("Warper > Gefenia 3", "gefenia03", 266, 168);
|
||||
naviregisterwarp("Warper > Gefenia 4", "gefenia04", 130, 272);
|
||||
}
|
||||
naviregisterwarp("Warper > Geffen Dungeon 1", "gef_dun00", 104, 99);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Geffen Dungeon 2", "gef_dun01", 115, 236);
|
||||
naviregisterwarp("Warper > Geffen Dungeon 3", "gef_dun02", 106, 132);
|
||||
naviregisterwarp("Warper > Geffen Dungeon 4", "gef_dun03", 203, 200);
|
||||
}
|
||||
naviregisterwarp("Warper > Entrance", "glast_01", 370, 304);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Castle 1", "gl_cas01", 199, 29);
|
||||
naviregisterwarp("Warper > Castle 2", "gl_cas02", 104, 25);
|
||||
naviregisterwarp("Warper > Chivalry 1", "gl_knt01", 150, 15);
|
||||
naviregisterwarp("Warper > Chivalry 2", "gl_knt02", 157, 287);
|
||||
naviregisterwarp("Warper > Churchyard", "gl_chyard", 147, 15);
|
||||
naviregisterwarp("Warper > Culvert 1", "gl_sew01", 258, 255);
|
||||
naviregisterwarp("Warper > Culvert 2", "gl_sew02", 108, 291);
|
||||
naviregisterwarp("Warper > Culvert 3", "gl_sew03", 171, 283);
|
||||
naviregisterwarp("Warper > Culvert 4", "gl_sew04", 68, 277);
|
||||
naviregisterwarp("Warper > St. Abbey", "gl_church", 156, 7);
|
||||
naviregisterwarp("Warper > Staircase Dungeon", "gl_step", 12, 7);
|
||||
naviregisterwarp("Warper > Underground Cave 1", "gl_dun01", 133, 271);
|
||||
naviregisterwarp("Warper > Underground Cave 2", "gl_dun02", 224, 274);
|
||||
naviregisterwarp("Warper > Underground Prison 1", "gl_prison", 14, 70);
|
||||
naviregisterwarp("Warper > Underground Prison 2", "gl_prison1", 150, 14);
|
||||
}
|
||||
naviregisterwarp("Warper > Kunlun Dungeon 1", "gon_dun01", 153, 53);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Kunlun Dungeon 2", "gon_dun02", 28, 113);
|
||||
naviregisterwarp("Warper > Kunlun Dungeon 3", "gon_dun03", 68, 16);
|
||||
}
|
||||
naviregisterwarp("Warper > Hidden Dungeon 1", "prt_maze01", 176, 7);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Hidden Dungeon 2", "prt_maze02", 93, 20);
|
||||
naviregisterwarp("Warper > Hidden Dungeon 3", "prt_maze03", 23, 8);
|
||||
}
|
||||
naviregisterwarp("Warper > Ice Dungeon 1", "ice_dun01", 157, 14);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Ice Dungeon 2", "ice_dun02", 151, 155);
|
||||
naviregisterwarp("Warper > Ice Dungeon 3", "ice_dun03", 149, 22);
|
||||
naviregisterwarp("Warper > Ice Dungeon 4", "ice_dun04", 33, 158);
|
||||
}
|
||||
naviregisterwarp("Warper > Entrance", "jupe_cave", 140, 51);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Juperos 1", "juperos_01", 53, 247);
|
||||
naviregisterwarp("Warper > Juperos 2", "juperos_02", 37, 63);
|
||||
naviregisterwarp("Warper > Core", "jupe_core", 150, 285);
|
||||
}
|
||||
naviregisterwarp("Warper > Kiel Dungeon 1", "kh_dun01", 28, 226);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Kiel Dungeon 2", "kh_dun02", 41, 198);
|
||||
}
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Lasagna Dungeon 1", "lasa_dun01", 24, 143);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Lasagna Dungeon 2", "lasa_dun02", 22, 171);
|
||||
naviregisterwarp("Warper > Lasagna Dungeon 3", "lasa_dun03", 190, 18);
|
||||
}
|
||||
}
|
||||
naviregisterwarp("Warper > The Royal Tomb", "lou_dun01", 218, 196);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Inside the Royal Tomb", "lou_dun02", 282, 20);
|
||||
naviregisterwarp("Warper > Suei Long Gon", "lou_dun03", 165, 38);
|
||||
}
|
||||
naviregisterwarp("Warper > Magma Dungeon 1", "mag_dun01", 126, 68);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Magma Dungeon 2", "mag_dun02", 47, 30);
|
||||
}
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Malangdo Dungeon 1", "mal_dun01", 33, 230);
|
||||
}
|
||||
naviregisterwarp("Warper > Moscovia Dungeon 1", "mosk_dun01", 189, 48);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Moscovia Dungeon 2", "mosk_dun02", 165, 30);
|
||||
naviregisterwarp("Warper > Moscovia Dungeon 3", "mosk_dun03", 32, 135);
|
||||
}
|
||||
naviregisterwarp("Warper > Nidhogg's Dungeon 1", "nyd_dun01", 61, 239);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Nidhogg's Dungeon 2", "nyd_dun02", 60, 271);
|
||||
}
|
||||
naviregisterwarp("Warper > Odin Temple 1", "odin_tem01", 298, 167);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Odin Temple 2", "odin_tem02", 224, 149);
|
||||
naviregisterwarp("Warper > Odin Temple 3", "odin_tem03", 266, 280);
|
||||
}
|
||||
naviregisterwarp("Warper > Orc Dungeon 1", "orcsdun01", 32, 170);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Orc Dungeon 2", "orcsdun02", 21, 185);
|
||||
}
|
||||
naviregisterwarp("Warper > Payon Dungeon 1", "pay_dun00", 21, 183);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Payon Dungeon 2", "pay_dun01", 19, 33);
|
||||
naviregisterwarp("Warper > Payon Dungeon 3", "pay_dun02", 19, 63);
|
||||
naviregisterwarp("Warper > Payon Dungeon 4", "pay_dun03", 155, 159);
|
||||
naviregisterwarp("Warper > Payon Dungeon 5", "pay_dun04", 201, 204);
|
||||
}
|
||||
naviregisterwarp("Warper > Pyramids 1", "moc_pryd01", 192, 9);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Pyramids 2", "moc_pryd02", 10, 192);
|
||||
naviregisterwarp("Warper > Pyramids 3", "moc_pryd03", 100, 92);
|
||||
naviregisterwarp("Warper > Pyramids 4", "moc_pryd04", 181, 11);
|
||||
naviregisterwarp("Warper > Basement 1", "moc_pryd05", 94, 96);
|
||||
naviregisterwarp("Warper > Basement 2", "moc_pryd06", 192, 8);
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Basement 1 - Nightmare Mode", "moc_prydn1", 94, 96);
|
||||
naviregisterwarp("Warper > Basement 2 - Nightmare Mode", "moc_prydn2", 192, 8);
|
||||
}
|
||||
}
|
||||
naviregisterwarp("Warper > Rachel Sanctuary 1", "ra_san01", 140, 11);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Rachel Sanctuary 2", "ra_san02", 32, 21);
|
||||
naviregisterwarp("Warper > Rachel Sanctuary 3", "ra_san03", 8, 149);
|
||||
naviregisterwarp("Warper > Rachel Sanctuary 4", "ra_san04", 204, 218);
|
||||
naviregisterwarp("Warper > Rachel Sanctuary 5", "ra_san05", 150, 9);
|
||||
}
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Scaraba Hole 1", "dic_dun01", 364, 44);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Scaraba Hole 2", "dic_dun02", 101, 141);
|
||||
}
|
||||
}
|
||||
naviregisterwarp("Warper > Sphinx 1", "in_sphinx1", 288, 9);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Sphinx 2", "in_sphinx2", 149, 81);
|
||||
naviregisterwarp("Warper > Sphinx 3", "in_sphinx3", 210, 54);
|
||||
naviregisterwarp("Warper > Sphinx 4", "in_sphinx4", 10, 222);
|
||||
naviregisterwarp("Warper > Sphinx 5", "in_sphinx5", 100, 99);
|
||||
}
|
||||
naviregisterwarp("Warper > Sunken Ship 1", "treasure01", 69, 24);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Sunken Ship 2", "treasure02", 102, 27);
|
||||
}
|
||||
naviregisterwarp("Warper > Thanatos Tower 1", "tha_t01", 150, 39);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Thanatos Tower 2", "tha_t02", 150, 136);
|
||||
naviregisterwarp("Warper > Thanatos Tower 3", "tha_t03", 220, 158);
|
||||
naviregisterwarp("Warper > Thanatos Tower 4", "tha_t04", 59, 143);
|
||||
naviregisterwarp("Warper > Thanatos Tower 5", "tha_t05", 62, 11);
|
||||
naviregisterwarp("Warper > Thanatos Tower 6", "tha_t06", 89, 221);
|
||||
naviregisterwarp("Warper > Thanatos Tower 7", "tha_t07", 35, 166);
|
||||
naviregisterwarp("Warper > Thanatos Tower 8", "tha_t08", 93, 148);
|
||||
naviregisterwarp("Warper > Thanatos Tower 9", "tha_t09", 29, 107);
|
||||
naviregisterwarp("Warper > Thanatos Tower 10", "tha_t10", 159, 138);
|
||||
naviregisterwarp("Warper > Thanatos Tower 11", "tha_t11", 19, 20);
|
||||
naviregisterwarp("Warper > Thanatos Tower 12", "tha_t12", 130, 52);
|
||||
}
|
||||
naviregisterwarp("Warper > Thor Volcano 1", "thor_v01", 21, 228);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Thor Volcano 2", "thor_v02", 75, 205);
|
||||
naviregisterwarp("Warper > Thor Volcano 3", "thor_v03", 34, 272);
|
||||
}
|
||||
naviregisterwarp("Warper > Toy Factory 1", "xmas_dun01", 205, 15);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Toy Factory 2", "xmas_dun02", 129, 133);
|
||||
}
|
||||
naviregisterwarp("Warper > Entrance", "tur_dun01", 154, 49);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Turtle Dungeon 1", "tur_dun02", 148, 261);
|
||||
naviregisterwarp("Warper > Turtle Dungeon 2", "tur_dun03", 132, 189);
|
||||
naviregisterwarp("Warper > Turtle Dungeon 3", "tur_dun04", 100, 192);
|
||||
}
|
||||
naviregisterwarp("Warper > Carpenter's Shop in the Tree", "um_dun01", 42, 31);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Passage to a Foreign World", "um_dun02", 48, 30);
|
||||
naviregisterwarp("Warper > Hvergermil's Fountain", "yggdrasil01", 204, 78);
|
||||
}
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Bifrost Tower 1", "ecl_tdun01", 57, 13);
|
||||
if (!.OnlyFirstDun) {
|
||||
naviregisterwarp("Warper > Bifrost Tower 2", "ecl_tdun02", 64, 88);
|
||||
naviregisterwarp("Warper > Bifrost Tower 3", "ecl_tdun03", 45, 14);
|
||||
naviregisterwarp("Warper > Bifrost Tower 4", "ecl_tdun04", 26, 23);
|
||||
}
|
||||
}
|
||||
|
||||
// castles
|
||||
|
||||
naviregisterwarp("Warper > Neuschwanstein", "alde_gld", 48, 83);
|
||||
naviregisterwarp("Warper > Hohenschwangau", "alde_gld", 95, 249);
|
||||
naviregisterwarp("Warper > Nuenberg", "alde_gld", 142, 85);
|
||||
naviregisterwarp("Warper > Wuerzburg", "alde_gld", 239, 242);
|
||||
naviregisterwarp("Warper > Rothenburg", "alde_gld", 264, 90);
|
||||
naviregisterwarp("Warper > Repherion", "gef_fild13", 214, 75);
|
||||
naviregisterwarp("Warper > Eeyolbriggar", "gef_fild13", 308, 240);
|
||||
naviregisterwarp("Warper > Yesnelph", "gef_fild13", 143, 240);
|
||||
naviregisterwarp("Warper > Bergel", "gef_fild13", 193, 278);
|
||||
naviregisterwarp("Warper > Mersetzdeitz", "gef_fild13", 305, 87);
|
||||
naviregisterwarp("Warper > Bright Arbor", "pay_gld", 121, 233);
|
||||
naviregisterwarp("Warper > Scarlet Palace", "pay_gld", 295, 116);
|
||||
naviregisterwarp("Warper > Holy Shadow", "pay_gld", 317, 293);
|
||||
naviregisterwarp("Warper > Sacred Altar", "pay_gld", 140, 160);
|
||||
naviregisterwarp("Warper > Bamboo Grove Hill", "pay_gld", 204, 266);
|
||||
naviregisterwarp("Warper > Kriemhild", "prt_gld", 134, 65);
|
||||
naviregisterwarp("Warper > Swanhild", "prt_gld", 240, 128);
|
||||
naviregisterwarp("Warper > Fadhgridh", "prt_gld", 153, 137);
|
||||
naviregisterwarp("Warper > Skoegul", "prt_gld", 111, 240);
|
||||
naviregisterwarp("Warper > Gondul", "prt_gld", 208, 240);
|
||||
naviregisterwarp("Warper > Mardol", "aru_gld", 158, 272);
|
||||
naviregisterwarp("Warper > Cyr", "aru_gld", 83, 47);
|
||||
naviregisterwarp("Warper > Horn", "aru_gld", 68, 155);
|
||||
naviregisterwarp("Warper > Gefn", "aru_gld", 299, 345);
|
||||
naviregisterwarp("Warper > Banadis", "aru_gld", 292, 107);
|
||||
naviregisterwarp("Warper > Himinn", "sch_gld", 293, 100);
|
||||
naviregisterwarp("Warper > Andlangr", "sch_gld", 288, 252);
|
||||
naviregisterwarp("Warper > Viblainn", "sch_gld", 97, 196);
|
||||
naviregisterwarp("Warper > Hljod", "sch_gld", 137, 90);
|
||||
naviregisterwarp("Warper > Skidbladnir", "sch_gld", 71, 315);
|
||||
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Kafragarten 1", "te_alde_gld", 48, 83);
|
||||
naviregisterwarp("Warper > Kafragarten 2", "te_alde_gld", 95, 249);
|
||||
naviregisterwarp("Warper > Kafragarten 3", "te_alde_gld", 142, 85);
|
||||
naviregisterwarp("Warper > Kafragarten 4", "te_alde_gld", 239, 242);
|
||||
naviregisterwarp("Warper > Kafragarten 5", "te_alde_gld", 264, 90);
|
||||
naviregisterwarp("Warper > Gloria 1", "te_prt_gld", 134, 65);
|
||||
naviregisterwarp("Warper > Gloria 2", "te_prt_gld", 240, 128);
|
||||
naviregisterwarp("Warper > Gloria 3", "te_prt_gld", 153, 137);
|
||||
naviregisterwarp("Warper > Gloria 4", "te_prt_gld", 111, 240);
|
||||
naviregisterwarp("Warper > Gloria 5", "te_prt_gld", 208, 240);
|
||||
}
|
||||
|
||||
// guild dungeons
|
||||
naviregisterwarp("Warper > Baldur F1", "gld_dun01", 119, 93);
|
||||
naviregisterwarp("Warper > Luina F1", "gld_dun02", 39, 161);
|
||||
naviregisterwarp("Warper > Valkyrie F1", "gld_dun03", 50, 44);
|
||||
naviregisterwarp("Warper > Britoniah F1", "gld_dun04", 116, 45);
|
||||
naviregisterwarp("Warper > Arunafeltz", "arug_dun01", 199, 195);
|
||||
naviregisterwarp("Warper > Schwarzwald", "schg_dun01", 200,124);
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Baldur F2", "gld_dun01_2", 119, 93);
|
||||
naviregisterwarp("Warper > Hall of Abyss", "gld2_pay", 120, 130);
|
||||
naviregisterwarp("Warper > Luina F2", "gld_dun02_2", 39, 161);
|
||||
naviregisterwarp("Warper > Hall of Abyss", "gld2_ald", 147, 155);
|
||||
naviregisterwarp("Warper > Valkyrie F2", "gld_dun03_2", 50, 44);
|
||||
naviregisterwarp("Warper > Hall of Abyss", "gld2_prt", 140, 132);
|
||||
naviregisterwarp("Warper > Britoniah F2", "gld_dun04_2", 116, 45);
|
||||
naviregisterwarp("Warper > Hall of Abyss", "gld2_gef", 152, 118);
|
||||
naviregisterwarp("Warper > Kafragarten", "teg_dun01", 42, 36);
|
||||
naviregisterwarp("Warper > Gloria", "teg_dun02", 26, 160);
|
||||
}
|
||||
end;
|
||||
|
||||
// instances
|
||||
naviregisterwarp("Warper > Endless Tower", "e_tower", 72, 112);
|
||||
naviregisterwarp("Warper > Nidhoggur's Nest", "nyd_dun02", 95, 193);
|
||||
naviregisterwarp("Warper > Orc's Memory", "gef_fild10", 240, 198);
|
||||
naviregisterwarp("Warper > Sealed Shrine", "monk_test", 306, 143);
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Bakonawa Lake", "ma_scene01", 172, 175);
|
||||
naviregisterwarp("Warper > Bangungot Hospital 2F", "ma_dun01", 151, 8);
|
||||
naviregisterwarp("Warper > Buwaya Cave", "ma_fild02", 316, 317);
|
||||
naviregisterwarp("Warper > Devil Tower", "dali02", 137, 115);
|
||||
naviregisterwarp("Warper > Eclage Interior", "ecl_hub01", 129, 12);
|
||||
naviregisterwarp("Warper > Faceworms Nest", "dali", 85, 64);
|
||||
naviregisterwarp("Warper > Geffen Magic Tournament", "dali", 94, 141);
|
||||
naviregisterwarp("Warper > Ghost Palace", "dali02", 46, 128);
|
||||
naviregisterwarp("Warper > Hazy Forest", "bif_fild01", 161, 334);
|
||||
naviregisterwarp("Warper > Horror Toy Factory", "xmas", 234, 298);
|
||||
naviregisterwarp("Warper > Malangdo Culvert", "mal_in01", 164, 21);
|
||||
naviregisterwarp("Warper > Octopus Cave", "mal_dun01", 152, 230);
|
||||
naviregisterwarp("Warper > Old Glast Heim", "glast_01", 204, 268);
|
||||
naviregisterwarp("Warper > Sarah and Fenrir", "dali02", 92, 141);
|
||||
naviregisterwarp("Warper > Sara Memory", "dali", 133, 108);
|
||||
naviregisterwarp("Warper > Wolfchev's Laboratory", "lhz_dun04", 148, 269);
|
||||
}
|
||||
|
||||
|
||||
// special
|
||||
naviregisterwarp("Warper > Auction Hall", "auction_01", 22, 68);
|
||||
naviregisterwarp("Warper > Battlegrounds", "bat_room", 154, 150);
|
||||
naviregisterwarp("Warper > Casino", "cmd_in02", 179, 129);
|
||||
naviregisterwarp("Warper > Kunlun Arena", "gon_test", 48, 10);
|
||||
naviregisterwarp("Warper > Izlude Arena", "arena_room", 100, 88);
|
||||
naviregisterwarp("Warper > Monster Race Arena", "p_track01", 62, 41);
|
||||
naviregisterwarp("Warper > Turbo Track", "turbo_room", 99, 114);
|
||||
if (checkre(0)) {
|
||||
naviregisterwarp("Warper > Dimensional Rift", "dali", 113, 82);
|
||||
naviregisterwarp("Warper > Eden Group Headquarters", "moc_para01", 31, 14);
|
||||
naviregisterwarp("Warper > Para Market", "paramk", 97, 17);
|
||||
}
|
||||
|
||||
OnInit:
|
||||
.Satan_Morocc = true; // false will enable moc_fild 4,5,6,8,9,10,14,15 while disable moc_fild 20,21,22 Default is true.
|
||||
.OnlyFirstFld = false; // true will teleport to the first level of the Fields Default is false.
|
||||
|
@ -16,6 +16,7 @@ RAPIDYAML_INCLUDE = -I../../3rdparty/rapidyaml/src -I../../3rdparty/rapidyaml/ex
|
||||
MAP_OBJ = $(shell ls *.cpp | sed -e "s/\.cpp/\.o/g")
|
||||
#MAP_OBJ += $(shell ls *.c | sed -e "s/\.c/\.o/g")
|
||||
MAP_DIR_OBJ = $(MAP_OBJ:%=obj/%)
|
||||
MAP_GEN_DIR_OBJ = $(MAP_OBJ:%=obj-gen/%)
|
||||
MAP_H = $(shell ls ../map/*.hpp) \
|
||||
$(shell ls ../config/*.hpp)
|
||||
|
||||
@ -34,6 +35,9 @@ else
|
||||
PCRE_CFLAGS=
|
||||
endif
|
||||
|
||||
TOOLS_DEPENDS=map-server-generator
|
||||
TOOLS_FLAGS="-DGENERATE_NAVI"
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
#####################################################################
|
||||
@ -43,6 +47,8 @@ all: $(ALL_DEPENDS)
|
||||
|
||||
server: $(SERVER_DEPENDS)
|
||||
|
||||
tools: $(TOOLS_DEPENDS)
|
||||
|
||||
clean:
|
||||
@echo " CLEAN map"
|
||||
@rm -rf *.o obj ../../@OMAP@@EXEEXT@
|
||||
@ -66,6 +72,10 @@ obj:
|
||||
@echo " MKDIR obj"
|
||||
@-mkdir obj
|
||||
|
||||
obj-gen:
|
||||
@echo " MDIR obj-gen"
|
||||
@-mkdir obj-gen
|
||||
|
||||
# executables
|
||||
|
||||
map-server: obj $(MAP_DIR_OBJ) $(COMMON_AR) $(LIBCONFIG_AR) $(RAPIDYAML_AR)
|
||||
@ -73,6 +83,11 @@ map-server: obj $(MAP_DIR_OBJ) $(COMMON_AR) $(LIBCONFIG_AR) $(RAPIDYAML_AR)
|
||||
@@CXX@ @LDFLAGS@ -o ../../@OMAP@@EXEEXT@ $(MAP_DIR_OBJ) $(COMMON_AR) $(LIBCONFIG_AR) $(RAPIDYAML_AR) @LIBS@ @PCRE_LIBS@ @MYSQL_LIBS@
|
||||
|
||||
|
||||
map-server-generator: obj-gen $(MAP_GEN_DIR_OBJ) $(COMMON_AR) $(LIBCONFIG_AR) $(RAPIDYAML_AR)
|
||||
@echo " LD map-server-generator@EXEEXT@"
|
||||
@@CXX@ @LDFLAGS@ -o ../../map-server-generator@EXEEXT@ $(MAP_GEN_DIR_OBJ) $(COMMON_AR) $(LIBCONFIG_AR) $(RAPIDYAML_AR) @LIBS@ @PCRE_LIBS@ @MYSQL_LIBS@
|
||||
|
||||
|
||||
# map object files
|
||||
#cause this one failling otherwise
|
||||
obj/npc.o: npc.cpp $(MAP_H) $(COMMON_H) $(LIBCONFIG_H) $(RAPIDYAML_H)
|
||||
@ -83,6 +98,14 @@ obj/%.o: %.cpp $(MAP_H) $(COMMON_H) $(LIBCONFIG_H) $(RAPIDYAML_H)
|
||||
@echo " CXX $<"
|
||||
@@CXX@ @CXXFLAGS@ $(COMMON_INCLUDE) $(LIBCONFIG_INCLUDE) $(PCRE_CFLAGS) $(RAPIDYAML_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
|
||||
|
||||
obj-gen/npc.o: npc.cpp $(MAP_H) $(COMMON_H) $(LIBCONFIG_H) $(RAPIDYAML_H)
|
||||
@echo " CXX $< (custom rule)"
|
||||
@@CXX@ @CXXFLAG_CLEARS@ $(TOOLS_FLAGS) $(COMMON_INCLUDE) $(LIBCONFIG_INCLUDE) $(PCRE_CFLAGS) $(RAPIDYAML_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
|
||||
|
||||
obj-gen/%.o: %.cpp $(MAP_H) $(COMMON_H) $(LIBCONFIG_H) $(RAPIDYAML_H)
|
||||
@echo " CXX $<"
|
||||
@@CXX@ @CXXFLAGS@ $(TOOLS_FLAGS) $(COMMON_INCLUDE) $(LIBCONFIG_INCLUDE) $(PCRE_CFLAGS) $(RAPIDYAML_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
|
||||
|
||||
# missing object files
|
||||
$(COMMON_AR):
|
||||
@$(MAKE) -C ../common server
|
||||
|
@ -10465,6 +10465,10 @@ void battle_adjust_conf()
|
||||
if (battle_config.custom_cell_stack_limit != 1)
|
||||
ShowWarning("Battle setting 'custom_cell_stack_limit' takes no effect as this server was compiled without Cell Stack Limit support.\n");
|
||||
#endif
|
||||
|
||||
#ifdef GENERATE_NAVI
|
||||
battle_config.dynamic_mobs = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
|
@ -209,6 +209,7 @@
|
||||
<ClInclude Include="mapreg.hpp" />
|
||||
<ClInclude Include="mercenary.hpp" />
|
||||
<ClInclude Include="mob.hpp" />
|
||||
<ClInclude Include="navi.hpp" />
|
||||
<ClInclude Include="npc.hpp" />
|
||||
<ClInclude Include="packets.hpp" />
|
||||
<ClInclude Include="packets_struct.hpp" />
|
||||
@ -256,6 +257,7 @@
|
||||
<ClCompile Include="mob.cpp">
|
||||
<Optimization Condition="'$(Configuration)'=='Release'">Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<ClCompile Include="navi.cpp" />
|
||||
<ClCompile Include="npc.cpp" />
|
||||
<ClCompile Include="npc_chat.cpp" />
|
||||
<ClCompile Include="party.cpp" />
|
||||
|
@ -95,6 +95,9 @@
|
||||
<ClInclude Include="mob.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="navi.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="npc.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -226,6 +229,9 @@
|
||||
<ClCompile Include="mob.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="navi.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="npc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "../config/core.hpp"
|
||||
|
||||
#include "../common/cbasetypes.hpp"
|
||||
#include "../common/cli.hpp"
|
||||
#include "../common/core.hpp"
|
||||
@ -41,6 +43,7 @@
|
||||
#include "mapreg.hpp"
|
||||
#include "mercenary.hpp"
|
||||
#include "mob.hpp"
|
||||
#include "navi.hpp"
|
||||
#include "npc.hpp"
|
||||
#include "party.hpp"
|
||||
#include "path.hpp"
|
||||
@ -4868,7 +4871,9 @@ void do_final(void){
|
||||
do_final_battle();
|
||||
do_final_chrif();
|
||||
do_final_clan();
|
||||
#ifndef GENERATE_NAVI
|
||||
do_final_clif();
|
||||
#endif
|
||||
do_final_npc();
|
||||
do_final_quest();
|
||||
do_final_achievement();
|
||||
@ -5203,7 +5208,9 @@ int do_init(int argc, char *argv[])
|
||||
do_init_instance();
|
||||
do_init_chrif();
|
||||
do_init_clan();
|
||||
#ifndef GENERATE_NAVI
|
||||
do_init_clif();
|
||||
#endif
|
||||
do_init_script();
|
||||
do_init_itemdb();
|
||||
do_init_channel();
|
||||
@ -5235,6 +5242,11 @@ int do_init(int argc, char *argv[])
|
||||
|
||||
ShowStatus("Server is '" CL_GREEN "ready" CL_RESET "' and listening on port '" CL_WHITE "%d" CL_RESET "'.\n\n", map_port);
|
||||
|
||||
#ifdef GENERATE_NAVI
|
||||
navi_create_lists();
|
||||
runflag = CORE_ST_STOP;
|
||||
#endif
|
||||
|
||||
if( runflag != CORE_ST_STOP )
|
||||
{
|
||||
shutdown_callback = do_shutdown;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "../common/timer.hpp"
|
||||
#include "../config/core.hpp"
|
||||
|
||||
#include "navi.hpp"
|
||||
#include "script.hpp"
|
||||
|
||||
struct npc_data;
|
||||
@ -812,6 +813,13 @@ struct map_data {
|
||||
|
||||
/* speeds up clif_updatestatus processing by causing hpmeter to run only when someone with the permission can view it */
|
||||
unsigned short hpmeter_visible;
|
||||
#ifdef GENERATE_NAVI
|
||||
struct {
|
||||
std::vector<const struct npc_data *> npcs;
|
||||
std::vector<const struct navi_link *> warps_into;
|
||||
std::vector<const struct navi_link *> warps_outof;
|
||||
} navi;
|
||||
#endif
|
||||
};
|
||||
|
||||
/// Stores information about a remote map (for multi-mapserver setups).
|
||||
|
649
src/map/navi.cpp
Normal file
649
src/map/navi.cpp
Normal file
@ -0,0 +1,649 @@
|
||||
#include "../config/core.hpp"
|
||||
|
||||
#ifdef GENERATE_NAVI
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
#include "../common/db.hpp"
|
||||
#include "../common/showmsg.hpp"
|
||||
#include "../common/malloc.hpp"
|
||||
#include "map.hpp"
|
||||
#include "mob.hpp"
|
||||
#include "navi.hpp"
|
||||
#include "npc.hpp"
|
||||
#include "path.hpp"
|
||||
|
||||
|
||||
std::string filePrefix = "generated/clientside/data/luafiles514/lua files/navigation/";
|
||||
|
||||
#define SET_OPEN 0
|
||||
#define SET_CLOSED 1
|
||||
|
||||
#define PATH_DIR_NORTH 1
|
||||
#define PATH_DIR_WEST 2
|
||||
#define PATH_DIR_SOUTH 4
|
||||
#define PATH_DIR_EAST 8
|
||||
|
||||
// @name Structures and defines for A* pathfinding
|
||||
// @{
|
||||
|
||||
// Path node
|
||||
struct path_node {
|
||||
struct path_node *parent; // pointer to parent
|
||||
short x; // x coord
|
||||
short y; // y coord
|
||||
short g_cost; // Actual cost from start to this node
|
||||
short f_cost; // g_cost + heuristic(this, goal)
|
||||
short flag; // SET_OPEN / SET_CLOSED
|
||||
};
|
||||
|
||||
/// Binary heap of path nodes
|
||||
BHEAP_STRUCT_DECL(node_heap, struct path_node*);
|
||||
static BHEAP_STRUCT_VAR(node_heap, g_open_set); // use static heap for all path calculations
|
||||
// it get's initialized in do_init_path, freed in do_final_path.
|
||||
|
||||
/// Comparator for binary heap of path nodes (minimum cost at top)
|
||||
#define NODE_MINTOPCMP(i,j) ((i)->f_cost - (j)->f_cost)
|
||||
|
||||
#define calc_index(x,y) (((x)+(y)*MAX_WALKPATH_NAVI) & (MAX_WALKPATH_NAVI*MAX_WALKPATH_NAVI-1))
|
||||
|
||||
/// Estimates the cost from (x0,y0) to (x1,y1).
|
||||
/// This is inadmissible (overestimating) heuristic used by game client.
|
||||
#define heuristic(x0, y0, x1, y1) (MOVE_COST * (abs((x1) - (x0)) + abs((y1) - (y0)))) // Manhattan distance
|
||||
/// @}
|
||||
|
||||
// Translates dx,dy into walking direction
|
||||
static enum directions walk_choices [3][3] =
|
||||
{
|
||||
{DIR_NORTHWEST,DIR_NORTH,DIR_NORTHEAST},
|
||||
{DIR_WEST,DIR_CENTER,DIR_EAST},
|
||||
{DIR_SOUTHWEST,DIR_SOUTH,DIR_SOUTHEAST},
|
||||
};
|
||||
|
||||
|
||||
/// @name A* pathfinding related functions
|
||||
/// @{
|
||||
|
||||
/// Pushes path_node to the binary node_heap.
|
||||
/// Ensures there is enough space in array to store new element.
|
||||
|
||||
#define swap_ptrcast_pathnode(a, b) swap_ptrcast(struct path_node *, a, b)
|
||||
|
||||
static void heap_push_node(struct node_heap *heap, struct path_node *node)
|
||||
{
|
||||
#ifndef __clang_analyzer__ // TODO: Figure out why clang's static analyzer doesn't like this
|
||||
BHEAP_ENSURE2(*heap, 1, 256, struct path_node **);
|
||||
BHEAP_PUSH2(*heap, node, NODE_MINTOPCMP, swap_ptrcast_pathnode);
|
||||
#endif // __clang_analyzer__
|
||||
}
|
||||
|
||||
/// Updates path_node in the binary node_heap.
|
||||
static int heap_update_node(struct node_heap *heap, struct path_node *node)
|
||||
{
|
||||
int i;
|
||||
ARR_FIND(0, BHEAP_LENGTH(*heap), i, BHEAP_DATA(*heap)[i] == node);
|
||||
if (i == BHEAP_LENGTH(*heap)) {
|
||||
ShowError("heap_update_node: node not found\n");
|
||||
return 1;
|
||||
}
|
||||
BHEAP_UPDATE(*heap, i, NODE_MINTOPCMP, swap_ptrcast_pathnode);
|
||||
return 0;
|
||||
}
|
||||
// end 1:1 copy of definitions from path.cpp
|
||||
|
||||
|
||||
// So we don't have to allocate every time, use static structures
|
||||
static struct path_node tp[MAX_WALKPATH_NAVI * MAX_WALKPATH_NAVI + 1];
|
||||
static int tpused[MAX_WALKPATH_NAVI * MAX_WALKPATH_NAVI + 1];
|
||||
|
||||
/// Path_node processing in A* pathfinding.
|
||||
/// Adds new node to heap and updates/re-adds old ones if necessary.
|
||||
static int add_path(struct node_heap *heap, int16 x, int16 y, int g_cost, struct path_node *parent, int h_cost)
|
||||
{
|
||||
int i = calc_index(x, y);
|
||||
|
||||
if (tpused[i] && tpused[i] == 1 + (x << 16 | y)) { // We processed this node before
|
||||
if (g_cost < tp[i].g_cost) { // New path to this node is better than old one
|
||||
// Update costs and parent
|
||||
tp[i].g_cost = g_cost;
|
||||
tp[i].parent = parent;
|
||||
tp[i].f_cost = g_cost + h_cost;
|
||||
if (tp[i].flag == SET_CLOSED) {
|
||||
heap_push_node(heap, &tp[i]); // Put it in open set again
|
||||
}
|
||||
else if (heap_update_node(heap, &tp[i])) {
|
||||
return 1;
|
||||
}
|
||||
tp[i].flag = SET_OPEN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tpused[i]) // Index is already taken; see `tp` array FIXME for details
|
||||
return 1;
|
||||
|
||||
// New node
|
||||
tp[i].x = x;
|
||||
tp[i].y = y;
|
||||
tp[i].g_cost = g_cost;
|
||||
tp[i].parent = parent;
|
||||
tp[i].f_cost = g_cost + h_cost;
|
||||
tp[i].flag = SET_OPEN;
|
||||
tpused[i] = 1 + (x << 16 | y);
|
||||
heap_push_node(heap, &tp[i]);
|
||||
return 0;
|
||||
}
|
||||
///@}
|
||||
|
||||
/*==========================================
|
||||
* path search (from)->(dest)
|
||||
* wpd: path info will be written here
|
||||
* cell: type of obstruction to check for
|
||||
*
|
||||
* Note: uses global g_open_set, therefore this method can't be called in parallel or recursivly.
|
||||
*------------------------------------------*/
|
||||
bool navi_path_search(struct navi_walkpath_data *wpd, const struct navi_pos *from, const struct navi_pos *dest, cell_chk cell) {
|
||||
register int i, x, y, dx = 0, dy = 0;
|
||||
struct map_data *mapdata = map_getmapdata(from->m);
|
||||
struct navi_walkpath_data s_wpd;
|
||||
|
||||
if (wpd == NULL)
|
||||
wpd = &s_wpd; // use dummy output variable
|
||||
|
||||
if (from->m != dest->m)
|
||||
return false;
|
||||
|
||||
if (!mapdata->cell)
|
||||
return false;
|
||||
|
||||
//Do not check starting cell as that would get you stuck.
|
||||
if (from->x < 0 || from->x > mapdata->xs || from->y < 0 || from->y > mapdata->ys /*|| map_getcellp(mapdata,x0,y0,cell)*/)
|
||||
return false;
|
||||
|
||||
// Check destination cell
|
||||
if (dest->x < 0 || dest->x > mapdata->xs || dest->y < 0 || dest->y > mapdata->ys || map_getcellp(mapdata, dest->x, dest->y, cell))
|
||||
return false;
|
||||
|
||||
|
||||
if (from->x == dest->x && from->y == dest->y) {
|
||||
wpd->path_len = 0;
|
||||
wpd->path_pos = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct path_node *current, *it;
|
||||
int xs = mapdata->xs - 1;
|
||||
int ys = mapdata->ys - 1;
|
||||
int len = 0;
|
||||
int j;
|
||||
|
||||
// A* (A-star) pathfinding
|
||||
// We always use A* for finding walkpaths because it is what game client uses.
|
||||
// Easy pathfinding cuts corners of non-walkable cells, but client always walks around it.
|
||||
BHEAP_RESET(g_open_set);
|
||||
|
||||
memset(tpused, 0, sizeof(tpused));
|
||||
|
||||
// Start node
|
||||
i = calc_index(from->x, from->y);
|
||||
tp[i].parent = NULL;
|
||||
tp[i].x = from->x;
|
||||
tp[i].y = from->y;
|
||||
tp[i].g_cost = 0;
|
||||
tp[i].f_cost = heuristic(from->x, from->y, dest->x, dest->y);
|
||||
tp[i].flag = SET_OPEN;
|
||||
tpused[i] = 1 + (from->x << 16 | from->y);
|
||||
|
||||
heap_push_node(&g_open_set, &tp[i]); // Put start node to 'open' set
|
||||
|
||||
for (;;) {
|
||||
int e = 0; // error flag
|
||||
|
||||
// Saves allowed directions for the current cell. Diagonal directions
|
||||
// are only allowed if both directions around it are allowed. This is
|
||||
// to prevent cutting corner of nearby wall.
|
||||
// For example, you can only go NW from the current cell, if you can
|
||||
// go N *and* you can go W. Otherwise you need to walk around the
|
||||
// (corner of the) non-walkable cell.
|
||||
int allowed_dirs = 0;
|
||||
|
||||
int g_cost;
|
||||
|
||||
if (BHEAP_LENGTH(g_open_set) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
current = BHEAP_PEEK(g_open_set); // Look for the lowest f_cost node in the 'open' set
|
||||
BHEAP_POP2(g_open_set, NODE_MINTOPCMP, swap_ptrcast_pathnode); // Remove it from 'open' set
|
||||
|
||||
x = current->x;
|
||||
y = current->y;
|
||||
g_cost = current->g_cost;
|
||||
|
||||
current->flag = SET_CLOSED; // Add current node to 'closed' set
|
||||
|
||||
if (x == dest->x && y == dest->y) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (y < ys && !map_getcellp(mapdata, x, y+1, cell)) allowed_dirs |= PATH_DIR_NORTH;
|
||||
if (y > 0 && !map_getcellp(mapdata, x, y-1, cell)) allowed_dirs |= PATH_DIR_SOUTH;
|
||||
if (x < xs && !map_getcellp(mapdata, x+1, y, cell)) allowed_dirs |= PATH_DIR_EAST;
|
||||
if (x > 0 && !map_getcellp(mapdata, x-1, y, cell)) allowed_dirs |= PATH_DIR_WEST;
|
||||
|
||||
#define chk_dir(d) ((allowed_dirs & (d)) == (d))
|
||||
// Process neighbors of current node
|
||||
if (chk_dir(PATH_DIR_SOUTH|PATH_DIR_EAST) && !map_getcellp(mapdata, x+1, y-1, cell))
|
||||
e += add_path(&g_open_set, x+1, y-1, g_cost + MOVE_DIAGONAL_COST, current, heuristic(x+1, y-1, dest->x, dest->y)); // (x+1, y-1) 5
|
||||
if (chk_dir(PATH_DIR_EAST))
|
||||
e += add_path(&g_open_set, x+1, y, g_cost + MOVE_COST, current, heuristic(x+1, y, dest->x, dest->y)); // (x+1, y) 6
|
||||
if (chk_dir(PATH_DIR_NORTH|PATH_DIR_EAST) && !map_getcellp(mapdata, x+1, y+1, cell))
|
||||
e += add_path(&g_open_set, x+1, y+1, g_cost + MOVE_DIAGONAL_COST, current, heuristic(x+1, y+1, dest->x, dest->y)); // (x+1, y+1) 7
|
||||
if (chk_dir(PATH_DIR_NORTH))
|
||||
e += add_path(&g_open_set, x, y+1, g_cost + MOVE_COST, current, heuristic(x, y+1, dest->x, dest->y)); // (x, y+1) 0
|
||||
if (chk_dir(PATH_DIR_NORTH|PATH_DIR_WEST) && !map_getcellp(mapdata, x-1, y+1, cell))
|
||||
e += add_path(&g_open_set, x-1, y+1, g_cost + MOVE_DIAGONAL_COST, current, heuristic(x-1, y+1, dest->x, dest->y)); // (x-1, y+1) 1
|
||||
if (chk_dir(PATH_DIR_WEST))
|
||||
e += add_path(&g_open_set, x-1, y, g_cost + MOVE_COST, current, heuristic(x-1, y, dest->x, dest->y)); // (x-1, y) 2
|
||||
if (chk_dir(PATH_DIR_SOUTH|PATH_DIR_WEST) && !map_getcellp(mapdata, x-1, y-1, cell))
|
||||
e += add_path(&g_open_set, x-1, y-1, g_cost + MOVE_DIAGONAL_COST, current, heuristic(x-1, y-1, dest->x, dest->y)); // (x-1, y-1) 3
|
||||
if (chk_dir(PATH_DIR_SOUTH))
|
||||
e += add_path(&g_open_set, x, y-1, g_cost + MOVE_COST, current, heuristic(x, y-1, dest->x, dest->y)); // (x, y-1) 4
|
||||
#undef chk_dir
|
||||
if (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (it = current; it->parent != NULL; it = it->parent, len++);
|
||||
if (len > sizeof(wpd->path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Recreate path
|
||||
wpd->path_len = len;
|
||||
wpd->path_pos = 0;
|
||||
|
||||
for (it = current, j = len-1; j >= 0; it = it->parent, j--) {
|
||||
dx = it->x - it->parent->x;
|
||||
dy = it->y - it->parent->y;
|
||||
wpd->path[j] = walk_choices[-dy + 1][dx + 1];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fileExists(const std::string& path) {
|
||||
std::ifstream in;
|
||||
in.open(path);
|
||||
|
||||
if (in.is_open()) {
|
||||
in.close();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void write_header(std::ostream &os, std::string name) {
|
||||
os << name << " = {\n";
|
||||
}
|
||||
|
||||
void write_footer(std::ostream &os) {
|
||||
os << "}\n";
|
||||
}
|
||||
|
||||
// 5001 = normal, 5002 = airport/airship, 5003 = indoor maps
|
||||
// 5001 = default
|
||||
// 5002 = airport/airship
|
||||
// 5003 = maps that are segmented
|
||||
// 5005 = 5003 + monsters??? i really have no clue
|
||||
// maybe it's maps that you must leave to reach parts of it
|
||||
// for example, ptr_fild04?
|
||||
int map_type(const struct map_data * m) {
|
||||
|
||||
bool segmented = false;
|
||||
bool has_mob = false;
|
||||
|
||||
if (strstr(m->name, "air"))
|
||||
return 5002;
|
||||
|
||||
// this is n^2, yikes!
|
||||
if (std::find_if(m->navi.warps_outof.begin(), m->navi.warps_outof.end(), [&m](const navi_link* link) {
|
||||
return std::find_if(m->navi.warps_outof.begin(), m->navi.warps_outof.end(), [&link](const navi_link* link2) {
|
||||
// find if any two warps in a map cannot be reached
|
||||
return !navi_path_search(nullptr, &link->pos, &link2->pos, CELL_CHKNOREACH);
|
||||
}) != m->navi.warps_into.end();
|
||||
}) != m->navi.warps_into.end())
|
||||
segmented = true;
|
||||
|
||||
if (m->moblist[0] != nullptr) {
|
||||
has_mob = true;
|
||||
}
|
||||
|
||||
if (segmented && has_mob) {
|
||||
return 5005;
|
||||
} else if (segmented) {
|
||||
return 5003;
|
||||
}
|
||||
|
||||
return 5001;
|
||||
}
|
||||
|
||||
void write_map(std::ostream& os, const struct map_data * m) {
|
||||
os << "\t{\"" << m->name << "\", \"" << m->name << "\", ";
|
||||
os << map_type(m) << ", " << m->xs << ", " << m->ys << "},\n";
|
||||
}
|
||||
|
||||
void write_warp(std::ostream& os, const struct navi_link &nl) {
|
||||
const struct map_data *msrc, *mdest;
|
||||
|
||||
msrc = map_getmapdata(nl.pos.m);
|
||||
mdest = map_getmapdata(nl.warp_dest.m);
|
||||
|
||||
if (msrc == nullptr || mdest == nullptr)
|
||||
return;
|
||||
|
||||
os << "\t{";
|
||||
os << "\"" << msrc->name << "\", ";
|
||||
os << nl.id << ", "; // gid
|
||||
// 200 = warp , 201 = npc script, 202 = Kafra Dungeon Warp,
|
||||
// 203 = Cool Event Dungeon Warp, 204 Kafra/Cool Event/Alberta warp,
|
||||
// 205 = airport (currently we only support warps)
|
||||
os << ((nl.npc->subtype == NPCTYPE_WARP) ? 200 : 201) << ", ";
|
||||
// sprite id, 99999 = warp portal
|
||||
os << ((nl.npc->vd.class_ == JT_WARPNPC) ? 99999 : (int)nl.npc->vd.class_) << ", ";
|
||||
if (nl.name.empty())
|
||||
os << "\"" << msrc->name << "_" << mdest->name << "_" << nl.id << "\", ";
|
||||
else
|
||||
os << "\"" << nl.name << "\", ";
|
||||
os << "\"\", "; // unique name
|
||||
os << nl.pos.x << ", " << nl.pos.y << ", ";
|
||||
os << "\"" << mdest->name << "\", ";
|
||||
os << nl.warp_dest.x << ", " << nl.warp_dest.y;
|
||||
os << "},\n";
|
||||
}
|
||||
|
||||
void write_npc(std::ostream &os, const struct npc_data *nd) {
|
||||
if (nd == nullptr) {
|
||||
ShowError("Unable to find NPC ID for NPC '%s'. Skipping...\n", nd->exname);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string name = nd->name;
|
||||
std::string visible_name = name.substr(0, name.find('#'));
|
||||
|
||||
const struct map_data *m;
|
||||
|
||||
m = map_getmapdata(nd->navi.pos.m);
|
||||
|
||||
os << "\t{ ";
|
||||
os << "\"" << m->name << "\", ";
|
||||
os << nd->navi.id << ", ";
|
||||
os << ((nd->subtype == NPCTYPE_SHOP || nd->subtype == NPCTYPE_CASHSHOP) ? 102 : 101) << ", ";
|
||||
os << nd->class_ << ", ";
|
||||
os << "\"" << visible_name << "\", ";
|
||||
os << "\"\", ";
|
||||
os << nd->navi.pos.x << ", " << nd->navi.pos.y;
|
||||
os << "},\n";
|
||||
}
|
||||
|
||||
void write_spawn(std::ostream &os, const struct map_data * m, const std::shared_ptr<s_mob_db> mobinfo, int amount, int idx) {
|
||||
|
||||
os << "\t{";
|
||||
os << "\"" << m->name << "\", ";
|
||||
os << "" << idx << ", ";
|
||||
os << "" << (mobinfo->mexp ? 301 : 300) << ", ";
|
||||
#if PACKETVER >= 20140000
|
||||
os << "" << (amount << 16 | (mobinfo->vd.class_ & 0xFFFF)) << ", ";
|
||||
#else
|
||||
os << "\t\t" << mobinfo->vd.class_ << ", ";
|
||||
#endif
|
||||
os << "\"" << mobinfo->jname.c_str() << "\", "; //c_str'ed because the strings have been resized to 24
|
||||
os << "\"" << mobinfo->sprite.c_str() << "\", ";
|
||||
os << "" << mobinfo->lv << ", ";
|
||||
os << "" <<
|
||||
(((mobinfo->status.ele_lv * 20 + mobinfo->status.def_ele) << 16)
|
||||
| (mobinfo->status.size << 8)
|
||||
| mobinfo->status.race);
|
||||
os << "},\n";
|
||||
|
||||
}
|
||||
|
||||
void write_object_lists() {
|
||||
auto mob_file = std::ofstream(filePrefix + "./navi_mob_krpri.lub");
|
||||
auto links_file = std::ofstream(filePrefix + "./navi_link_krpri.lub");
|
||||
auto npc_file = std::ofstream(filePrefix + "./navi_npc_krpri.lub");
|
||||
auto map_file = std::ofstream(filePrefix + "./navi_map_krpri.lub");
|
||||
|
||||
int warp_count = 0;
|
||||
int npc_count = 0;
|
||||
int spawn_count = 0;
|
||||
|
||||
write_header(links_file, "Navi_Link");
|
||||
write_header(npc_file, "Navi_Npc");
|
||||
write_header(mob_file, "Navi_Mob");
|
||||
write_header(map_file, "Navi_Map");
|
||||
|
||||
for (int mapid = 0; mapid < map_num; mapid++) {
|
||||
auto m = map_getmapdata(mapid);
|
||||
|
||||
// Warps/NPCs
|
||||
for (int npcidx = 0; npcidx < m->npc_num; npcidx++) {
|
||||
struct npc_data *nd = m->npc[npcidx];
|
||||
|
||||
if (nd == nullptr)
|
||||
continue;
|
||||
|
||||
if (nd->subtype == NPCTYPE_WARP) {
|
||||
int target = nd->navi.warp_dest.m;
|
||||
if (target < 0)
|
||||
continue;
|
||||
|
||||
nd->navi.id = 13350 + warp_count++;
|
||||
write_warp(links_file, nd->navi);
|
||||
m->navi.warps_outof.push_back(&nd->navi);
|
||||
map[target].navi.warps_into.push_back(&nd->navi);
|
||||
|
||||
} else { // Other NPCs
|
||||
if (nd->class_ == -1 || nd->class_ == JT_HIDDEN_NPC
|
||||
|| nd->class_ == JT_HIDDEN_WARP_NPC || nd->class_ == JT_GUILD_FLAG
|
||||
|| nd->navi.hidden)
|
||||
continue;
|
||||
|
||||
nd->navi.id = 11984 + npc_count;
|
||||
write_npc(npc_file, nd);
|
||||
m->navi.npcs.push_back(nd);
|
||||
|
||||
for (auto &link : nd->links) {
|
||||
int target = link.warp_dest.m;
|
||||
if (target < 0)
|
||||
continue;
|
||||
|
||||
link.id = 13350 + warp_count++;
|
||||
write_warp(links_file, link);
|
||||
m->navi.warps_outof.push_back(&link);
|
||||
map[target].navi.warps_into.push_back(&link);
|
||||
}
|
||||
|
||||
npc_count++;
|
||||
}
|
||||
}
|
||||
|
||||
// Mobs
|
||||
for (int mobidx = 0; mobidx < MAX_MOB_LIST_PER_MAP; mobidx++) {
|
||||
if (m->moblist[mobidx] == nullptr)
|
||||
continue;
|
||||
|
||||
const auto mobinfo = mob_db.find(m->moblist[mobidx]->id);
|
||||
if (mobinfo == nullptr)
|
||||
continue;
|
||||
|
||||
write_spawn(mob_file, m, mobinfo, m->moblist[mobidx]->num, 17104 + spawn_count);
|
||||
spawn_count++;
|
||||
}
|
||||
write_map(map_file, m);
|
||||
}
|
||||
|
||||
ShowStatus("Generated %d maps\n", map_num);
|
||||
ShowStatus("Generated %d npcs\n", npc_count);
|
||||
ShowStatus("Generated %d mobs\n", spawn_count);
|
||||
ShowStatus("Generated %d links\n", warp_count);
|
||||
|
||||
write_footer(map_file);
|
||||
write_footer(links_file);
|
||||
write_footer(npc_file);
|
||||
write_footer(mob_file);
|
||||
}
|
||||
|
||||
void write_map_header(std::ostream &os, const struct map_data * m) {
|
||||
os << "\t\"" << m->name << "\", " << m->navi.npcs.size() << ",\n";
|
||||
os << "\t{\n";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Given an NPC in a map (nd)
|
||||
For every warp into the map (warp)
|
||||
Find a path from nd to warp
|
||||
*/
|
||||
void write_npc_distance(std::ostream &os, const struct npc_data * nd, const struct map_data * msrc) {
|
||||
os << "\t\t{ " << nd->navi.id << ", -- (" << nd->name << " " << msrc->name << ", " << nd->navi.pos.x << ", " << nd->navi.pos.y << ")\n";
|
||||
for (const auto warp : msrc->navi.warps_into) {
|
||||
struct navi_walkpath_data wpd = {0};
|
||||
auto mdest = map_getmapdata(warp->pos.m);
|
||||
|
||||
// Find a path from the npc to the warp destination
|
||||
// The warp is into the map, so this makes sense
|
||||
if (!navi_path_search(&wpd, &nd->navi.pos, &warp->warp_dest, CELL_CHKNOREACH)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
os << "\t\t\t{ \"" << mdest->name << "\", " << warp->id << ", " << std::to_string(wpd.path_len) << "}, -- (" << msrc->name << ", " << warp->pos.x << ", " << warp->pos.y << ")\n";
|
||||
}
|
||||
os << "\t\t\t{\"\", 0, 0}\n";
|
||||
os << "\t\t},\n";
|
||||
}
|
||||
|
||||
void write_npc_distances() {
|
||||
auto dist_npc_file = std::ofstream(filePrefix + "./navi_npcdistance_krpri.lub");
|
||||
|
||||
write_header(dist_npc_file, "Navi_NpcDistance");
|
||||
|
||||
for (int mapid = 0; mapid < map_num; mapid++) {
|
||||
auto m = map_getmapdata(mapid);
|
||||
if (m->navi.npcs.size() == 0) {
|
||||
// ShowStatus("Skipped %s NPC distance table, no NPCs in map (%d/%d)\n", map[m].name, m, map_num);
|
||||
continue;
|
||||
}
|
||||
if (m->navi.warps_into.size() == 0) {
|
||||
// ShowStatus("Skipped %s NPC distance table, no warps into map (%d/%d)\n", map[m].name, m, map_num);
|
||||
continue;
|
||||
}
|
||||
|
||||
write_map_header(dist_npc_file, m);
|
||||
for (auto nd : m->navi.npcs) {
|
||||
write_npc_distance(dist_npc_file, nd, m);
|
||||
}
|
||||
dist_npc_file << "\t},\n";
|
||||
}
|
||||
|
||||
ShowStatus("Generated NPC Distances for %d maps\n", map_num);
|
||||
|
||||
write_footer(dist_npc_file);
|
||||
}
|
||||
|
||||
void write_mapdist_header(std::ostream &os, const struct map_data * m) {
|
||||
os << "\t\"" << m->name << "\", " << m->navi.warps_outof.size() << ",\n";
|
||||
os << "\t{\n";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Given a warp out of a map (warp1, m)
|
||||
for every warp out of the map (warp2)
|
||||
find a path from the warp1->src to warp2->src
|
||||
Add this as a "P" Warp
|
||||
|
||||
for every warp out of warp1->dest.m (warp3)
|
||||
find a path from warp1->dest to warp3->src
|
||||
Add this as an "E" Warp
|
||||
*/
|
||||
void write_map_distance(std::ostream &os, const struct navi_link * warp1, const struct map_data * m) {
|
||||
os << "\t\t{ " << warp1->id << ", -- (" << " " << m->name << ", " << warp1->pos.x << ", " << warp1->pos.y << ")\n";
|
||||
// for (const auto warp2 : m->navi.warps_outof) {
|
||||
// struct navi_walkpath_data wpd = {0};
|
||||
// if (warp1 == warp2)
|
||||
// continue;
|
||||
// if (!navi_path_search(&wpd, &warp1->pos, &warp2->pos, CELL_CHKNOREACH))
|
||||
// continue;
|
||||
// os << "\t\t\t{ \"P\", " << warp2->id << ", " << std::to_string(wpd.path_len) << "}, -- ReachableFromSrc warp (" << m->name << ", " << warp2->pos.x << ", " << warp2->pos.y << ")\n";
|
||||
// }
|
||||
|
||||
for (const auto warp3 : map_getmapdata(warp1->warp_dest.m)->navi.warps_outof) {
|
||||
struct navi_walkpath_data wpd = {0};
|
||||
|
||||
if (!navi_path_search(&wpd, &warp1->warp_dest, &warp3->pos, CELL_CHKNOREACH))
|
||||
continue;
|
||||
|
||||
os << "\t\t\t{ \"E\", " << warp3->id << ", " << std::to_string(wpd.path_len) << "}, -- ReachableFromDst warp (" << map_getmapdata(warp3->pos.m)->name << ", " << warp3->pos.x << ", " << warp3->pos.y << ")\n";
|
||||
}
|
||||
|
||||
os << "\t\t\t{\"NULL\", 0, 0}\n";
|
||||
os << "\t\t},\n";
|
||||
}
|
||||
|
||||
void write_map_distances() {
|
||||
auto dist_map_file = std::ofstream(filePrefix + "./navi_linkdistance_krpri.lub");
|
||||
write_header(dist_map_file, "Navi_Distance");
|
||||
|
||||
for (int mapid = 0; mapid < map_num; mapid++) {
|
||||
const struct map_data * m = map_getmapdata(mapid);
|
||||
write_mapdist_header(dist_map_file, m);
|
||||
for (auto nd : m->navi.warps_outof) {
|
||||
write_map_distance(dist_map_file, nd, m);
|
||||
}
|
||||
dist_map_file << "\t},\n";
|
||||
}
|
||||
ShowStatus("Generated Map Distances for %d maps\n", map_num);
|
||||
write_footer(dist_map_file);
|
||||
}
|
||||
|
||||
|
||||
void navi_create_lists() {
|
||||
BHEAP_INIT(g_open_set);
|
||||
|
||||
auto starttime = std::chrono::system_clock::now();
|
||||
|
||||
if (!fileExists(filePrefix)) {
|
||||
ShowError("File directory %s does not exist.\n", filePrefix.c_str());
|
||||
ShowInfo("Create the directory and rerun map-server");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
npc_event_runall(script_config.navi_generate_name);
|
||||
|
||||
write_object_lists();
|
||||
auto currenttime = std::chrono::system_clock::now();
|
||||
ShowInfo("Object lists took %ums\n", std::chrono::duration_cast<std::chrono::milliseconds>(currenttime - starttime));
|
||||
starttime = std::chrono::system_clock::now();
|
||||
write_npc_distances();
|
||||
currenttime = std::chrono::system_clock::now();
|
||||
ShowInfo("NPC Distances took %ums\n", std::chrono::duration_cast<std::chrono::milliseconds>(currenttime - starttime));
|
||||
starttime = std::chrono::system_clock::now();
|
||||
write_map_distances();
|
||||
currenttime = std::chrono::system_clock::now();
|
||||
ShowInfo("Link Distances took %ums\n", std::chrono::duration_cast<std::chrono::milliseconds>(currenttime - starttime));
|
||||
|
||||
BHEAP_CLEAR(g_open_set);
|
||||
}
|
||||
|
||||
#endif
|
43
src/map/navi.hpp
Normal file
43
src/map/navi.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef NAVI_H
|
||||
#define NAVI_H
|
||||
|
||||
#include "../config/core.hpp"
|
||||
|
||||
#ifdef GENERATE_NAVI
|
||||
struct navi_pos {
|
||||
int m;
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
struct npc_data;
|
||||
|
||||
struct navi_npc {
|
||||
struct npc_data * npc;
|
||||
int id;
|
||||
struct navi_pos pos;
|
||||
|
||||
};
|
||||
|
||||
struct navi_link {
|
||||
struct npc_data * npc;
|
||||
int id;
|
||||
struct navi_pos pos;
|
||||
struct navi_pos warp_dest; // only set for warps
|
||||
bool hidden; // hidden by script
|
||||
std::string name; // custom name
|
||||
};
|
||||
|
||||
|
||||
// We need a bigger max path length than stock walkpath
|
||||
#define MAX_WALKPATH_NAVI 1024
|
||||
|
||||
struct navi_walkpath_data {
|
||||
uint8 path_len, path_pos;
|
||||
uint8 path[MAX_WALKPATH_NAVI];
|
||||
};
|
||||
|
||||
|
||||
void navi_create_lists();
|
||||
#endif // ifdef GENERATE_NAVI
|
||||
#endif
|
@ -30,6 +30,7 @@
|
||||
#include "log.hpp"
|
||||
#include "map.hpp"
|
||||
#include "mob.hpp"
|
||||
#include "navi.hpp"
|
||||
#include "pc.hpp"
|
||||
#include "pet.hpp"
|
||||
#include "script.hpp" // script_config
|
||||
@ -3715,6 +3716,12 @@ struct npc_data *npc_create_npc(int16 m, int16 x, int16 y){
|
||||
nd->progressbar.timeout = 0;
|
||||
nd->vd = npc_viewdb[0]; // Default to JT_INVISIBLE
|
||||
|
||||
#ifdef GENERATE_NAVI
|
||||
nd->navi.pos = {m, x, y};
|
||||
nd->navi.id = 0;
|
||||
nd->navi.npc = nd;
|
||||
#endif
|
||||
|
||||
return nd;
|
||||
}
|
||||
|
||||
@ -3834,6 +3841,11 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const
|
||||
nd->u.warp.y = to_y;
|
||||
nd->u.warp.xs = xs;
|
||||
nd->u.warp.ys = ys;
|
||||
|
||||
#ifdef GENERATE_NAVI
|
||||
nd->navi.warp_dest = {map_mapindex2mapid(i), to_x, to_y};
|
||||
#endif
|
||||
|
||||
npc_warp++;
|
||||
nd->bl.type = BL_NPC;
|
||||
nd->subtype = NPCTYPE_WARP;
|
||||
|
@ -9,11 +9,13 @@
|
||||
|
||||
#include "../common/database.hpp"
|
||||
#include "../common/timer.hpp"
|
||||
#include "../config/core.hpp"
|
||||
|
||||
#include "clif.hpp" //
|
||||
#include "map.hpp" // struct block_list
|
||||
#include "status.hpp" // struct status_change
|
||||
#include "unit.hpp" // struct unit_data
|
||||
#include "navi.hpp" // navi stuff
|
||||
|
||||
struct block_list;
|
||||
struct npc_data;
|
||||
@ -205,6 +207,11 @@ struct npc_data {
|
||||
t_tick timeout;
|
||||
unsigned long color;
|
||||
} progressbar;
|
||||
|
||||
#ifdef GENERATE_NAVI
|
||||
struct navi_link navi; // for warps and the src of npcs
|
||||
std::vector<navi_link> links; // for extra links, like warper npc
|
||||
#endif
|
||||
};
|
||||
|
||||
struct eri;
|
||||
|
@ -306,6 +306,7 @@ struct Script_Config script_config = {
|
||||
// Instance related
|
||||
"OnInstanceInit", //instance_init_event_name (is executed right after instance creation)
|
||||
"OnInstanceDestroy", //instance_destroy_event_name (is executed right before instance destruction)
|
||||
"OnNaviGenerate", //navi_generate_name (is executed right before navi generation)
|
||||
};
|
||||
|
||||
static jmp_buf error_jump;
|
||||
@ -25827,7 +25828,38 @@ BUILDIN_FUNC(getenchantgrade){
|
||||
script_pushint(st, -1);
|
||||
else
|
||||
script_pushint(st, sd->inventory.u.items_inventory[index].enchantgrade);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
BUILDIN_FUNC(naviregisterwarp) {
|
||||
#ifdef GENERATE_NAVI
|
||||
TBL_NPC* nd;
|
||||
int x, y, m;
|
||||
const char *warpname, *mapname=NULL;
|
||||
|
||||
struct navi_link link;
|
||||
|
||||
nd = map_id2nd(st->oid);
|
||||
if (!nd) {
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
warpname = script_getstr(st, 2);
|
||||
mapname = script_getstr(st, 3);
|
||||
x = script_getnum(st,4);
|
||||
y = script_getnum(st,5);
|
||||
m = map_mapname2mapid(mapname);
|
||||
|
||||
link.npc = nd;
|
||||
link.id = 0;
|
||||
link.pos = nd->navi.pos;
|
||||
link.warp_dest = {m, x, y};
|
||||
link.name = warpname;
|
||||
link.hidden = nd->navi.hidden;
|
||||
|
||||
nd->links.push_back(link);
|
||||
|
||||
#endif
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@ -25875,6 +25907,23 @@ BUILDIN_FUNC( openstylist ){
|
||||
#endif
|
||||
}
|
||||
|
||||
BUILDIN_FUNC(navihide) {
|
||||
#ifdef GENERATE_NAVI
|
||||
TBL_NPC *nd;
|
||||
|
||||
nd = map_id2nd(st->oid);
|
||||
if (!nd) {
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
nd->navi.hidden = true;
|
||||
for (auto &link : nd->links) {
|
||||
link.hidden = true;
|
||||
}
|
||||
#endif
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
BUILDIN_FUNC(getitempos) {
|
||||
struct map_session_data* sd;
|
||||
|
||||
@ -26972,6 +27021,10 @@ struct script_function buildin_func[] = {
|
||||
BUILDIN_DEF(setinstancevar,"rvi"),
|
||||
BUILDIN_DEF(openstylist, "?"),
|
||||
|
||||
// Navigation Generation System
|
||||
BUILDIN_DEF(naviregisterwarp, "ssii"),
|
||||
BUILDIN_DEF(navihide, ""),
|
||||
|
||||
BUILDIN_DEF(getitempos,""),
|
||||
BUILDIN_DEF(laphine_synthesis, ""),
|
||||
BUILDIN_DEF(laphine_upgrade, ""),
|
||||
|
@ -211,6 +211,9 @@ struct Script_Config {
|
||||
// Instance related
|
||||
const char* instance_init_event_name;
|
||||
const char* instance_destroy_event_name;
|
||||
|
||||
// Navigation related
|
||||
const char* navi_generate_name;
|
||||
};
|
||||
extern struct Script_Config script_config;
|
||||
|
||||
|
123
tools/navi.py
Executable file
123
tools/navi.py
Executable file
@ -0,0 +1,123 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import re
|
||||
|
||||
|
||||
def parse_setarray(s):
|
||||
"""
|
||||
parse setarray
|
||||
returns list of x,y tuples
|
||||
"""
|
||||
# D1: setarray @c[2],261,272,275,270,116,27;
|
||||
res = re.match(r".*\],(.*);", s)
|
||||
# print(res.group(1))
|
||||
|
||||
spl = res.group(1).split(',')
|
||||
l = [spl[i:i + 2] for i in range(0, len(spl), 2)]
|
||||
# print(l)
|
||||
return l
|
||||
|
||||
|
||||
def parse_disp(s):
|
||||
"""
|
||||
parse disp
|
||||
returns name for all, or list of names for each
|
||||
"""
|
||||
# Disp("Comodo Field",1,9);
|
||||
res = re.match(r""".*"(.*)".*,.*(\d+),(\d+)\).*""", s)
|
||||
if res:
|
||||
# print(res.group(1))
|
||||
# print(res.group(2))
|
||||
# print(res.group(3))
|
||||
l = [f"{res.group(1)} {i}" for i in range(int(res.group(2)), int(res.group(3)) + 1)]
|
||||
# print(l)
|
||||
return l
|
||||
|
||||
res = re.match(r'.*Disp\("(.*)"\);.*', s)
|
||||
l = res.group(1).split(':')
|
||||
# print(l)
|
||||
return l
|
||||
|
||||
|
||||
def parse_pick(s):
|
||||
"""
|
||||
parse pick
|
||||
returns base fld for all, or list of flds for all
|
||||
"""
|
||||
if s.count('"') > 2:
|
||||
# need to return lsit of fields
|
||||
res = re.match(r'Pick\("",(.*)\).*', s)
|
||||
# print(res.group(1))
|
||||
l = res.group(1).split(',')
|
||||
l = [m[1:-1] for m in l], 0
|
||||
return l
|
||||
elif ',' in s:
|
||||
# need to subtract number
|
||||
res = re.match(r""".*\("(.*)".*(\d+).*\)""", s)
|
||||
# print(res.group(1))
|
||||
return res.group(1), int(res.group(2))
|
||||
else:
|
||||
res = re.match(r""".*\("(.*)"\)""", s)
|
||||
# print(res.group(1))
|
||||
return res.group(1), 0
|
||||
|
||||
|
||||
def split_disp_pick(s):
|
||||
"""
|
||||
returns tuple of <"disp(..)", "pick(...)">
|
||||
"""
|
||||
|
||||
res = re.match(r""".*(Disp\(.*\);).*(Pick\(.*\);).*""", s)
|
||||
# print(res.group(1))
|
||||
# print(res.group(2))
|
||||
return res.group(1), res.group(2)
|
||||
|
||||
|
||||
def gen_mapname(map, i, diff):
|
||||
"""
|
||||
take man_fild, 3, 0
|
||||
output man_fild03
|
||||
|
||||
diff is the subtract for gef_fild00
|
||||
"""
|
||||
if isinstance(map, str):
|
||||
i = i + 1 - diff
|
||||
return f"{map}{'0' if i < 10 else ''}{i}"
|
||||
elif isinstance(map, list):
|
||||
return map[i]
|
||||
else:
|
||||
raise Exception
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
# parse_disp('Disp("Sograt Desert 1:Sograt Desert 2:Sograt Desert 3:Sograt Desert 7:Sograt Desert 11:Sograt Desert 12:Sograt Desert 13:Sograt Desert 16:Sograt Desert 17:Sograt Desert 18:Sograt Desert 19:Sograt Desert 20:Sograt Desert 21:Sograt Desert 22");')
|
||||
# parse_setarray(
|
||||
# ' setarray @c[2],219,205,177,206,194,182,224,170,198,216,156,187,185,263,206,228,208,238,209,223,85,97,207,202,31,195,38,195;')
|
||||
# return
|
||||
|
||||
while (1):
|
||||
setarray = input("input setarray")
|
||||
disppick = input("input disppick")
|
||||
|
||||
poses = parse_setarray(setarray)
|
||||
disp, pick = split_disp_pick(disppick)
|
||||
|
||||
names = parse_disp(disp)
|
||||
maps, diff = parse_pick(pick)
|
||||
|
||||
for i in range(len(poses)):
|
||||
if i == 1:
|
||||
print("if (!.OnlyFirstDun) {")
|
||||
if i > 0:
|
||||
tabs = " "
|
||||
else:
|
||||
tabs = ""
|
||||
print(
|
||||
f'{tabs}naviregisterwarp("Warper > {names[i]}", "{gen_mapname(maps, i, diff)}", {poses[i][0]}, {poses[i][1]});')
|
||||
if i > 0 and i == len(poses) - 1:
|
||||
print("}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
x
Reference in New Issue
Block a user