Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 07/07/18 in Posts

  1. Heya, The following script commands replace addrid and they were initially implemented by Luxuri. The main advantage of these is that they do not attach the players on the current script, allowing an easier code flow. The commands: foreachinserver "<npc_label>" foreachinmap "<npc_label>", "<map_name>" foreachinparty "<npc_label>", <party_id> foreachinarea "<npc_label>", "<map_name>", <x1>, <y1>, <x2>, <y2> foreachinshootablerange "<npc_label>", "<map_name>", <x>, <y>, <range> foreachinguild "<npc_label>", <guild_id> prontera,155,185,3 script Test 77,{ foreachinserver("Test::OnEvent"); foreachinmap("Test::OnEvent", "prontera"); foreachinparty("Test::OnEvent", getcharid(1)); foreachinarea("Test::OnEvent", "this", 153, 182, 159, 177); foreachinshootablerange("Test::OnEvent", "this", 153, 182, 2); foreachinguild("Test::OnEvent", getcharid(2)); end; OnEvent: announce "Attached script to " + strcharinfo(0), 0; end; } For example, for making a script that kicks dead players without using OnPCDieEvent, you could use: prontera,155,185,3 script Test 77,{ initnpctimer; dispbottom "Kicking dead players."; end; OnTimer1000: .kicked = 0; foreachinmap("Test::OnKick", "prontera"); if (.kicked > 0) { announce .kicked + " player(s) have died!", 0; } initnpctimer; end; OnKick: if (HP <= 0) { .kicked++; getitem 501, 1; warp "alberta", 192, 147; percentheal 100, 100; } end; } You can easily make your own foreach methods (for BG, clans, etc). Diff file: diff --git a/src/map/npc.cpp b/src/map/npc.cpp index 647a765..c60a5d7 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -2224,6 +2224,20 @@ int npc_unload(struct npc_data* nd, bool single) { return 0; } +/// Returns the NPC associated with the specified event label. +struct npc_data* npc_event_label_nd(const char* labelname) +{ + struct event_data* ev = (struct event_data*)strdb_get(ev_db, labelname); + return (ev != NULL ? ev->nd : NULL); +} + +/// Returns the bytecode position that the specified event label refers to. +int npc_event_label_pos(const char* labelname) +{ + struct event_data* ev = (struct event_data*)strdb_get(ev_db, labelname); + return (ev != NULL ? ev->pos : -1); +} + // // NPC Source Files // diff --git a/src/map/npc.hpp b/src/map/npc.hpp index d6a9b97..3049651 100644 --- a/src/map/npc.hpp +++ b/src/map/npc.hpp @@ -1162,6 +1162,9 @@ bool npc_isnear(struct block_list * bl); int npc_get_new_npc_id(void); +struct npc_data* npc_event_label_nd(const char* labelname); +int npc_event_label_pos(const char* labelname); + int npc_addsrcfile(const char* name, bool loadscript); void npc_delsrcfile(const char* name); int npc_parsesrcfile(const char* filepath, bool runOnInit); diff --git a/src/map/script.cpp b/src/map/script.cpp index 180f9ba..5535094 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -12230,6 +12230,150 @@ BUILDIN_FUNC(isloggedin) return SCRIPT_CMD_SUCCESS; } +static int script_foreach_sub(TBL_PC* sd, const char* event) +{ + struct npc_data* nd; + int pos; + + if ((nd = npc_event_label_nd(event)) == NULL || (pos = npc_event_label_pos(event)) == -1) + return 0; + + run_script(nd->u.scr.script, pos, sd->bl.id, nd->bl.id); + return 1; +} + +static int script_foreach_sub_va_bl(struct block_list* bl, va_list args) { + const char* event = va_arg(args, const char*); + return script_foreach_sub((TBL_PC*)bl, event); +} + +static int script_foreach_sub_va_sd(TBL_PC* sd, va_list args) { + const char* event = va_arg(args, const char*); + return script_foreach_sub(sd, event); +} + +/// foreachinserver "<npc_label>" +BUILDIN_FUNC(foreachinserver) +{ + const char* event = script_getstr(st, 2); + map_foreachpc(script_foreach_sub_va_sd, event); + return SCRIPT_CMD_SUCCESS; +} + +/// foreachinmap "<npc_label>", "<map_name>" +BUILDIN_FUNC(foreachinmap) +{ + const char* event = script_getstr(st, 2); + const char* mapname = script_getstr(st, 3); + TBL_NPC* nd = map_id2nd(st->oid); + int16 m = (nd && strcmp(mapname, "this") == 0) ? nd->bl.m : map_mapname2mapid(mapname); + + if (m < 0) { + ShowWarning("buildin_foreachinmap: Invalid map name '%s'.\n", mapname); + return SCRIPT_CMD_SUCCESS; + } + + map_foreachinmap(script_foreach_sub_va_bl, m, BL_PC, event); + return SCRIPT_CMD_SUCCESS; +} + +/// foreachinparty "<npc_label>", <party_id> +BUILDIN_FUNC(foreachinparty) +{ + const char* event = script_getstr(st, 2); + int party_id = script_getnum(st, 3); + struct party_data* p; + int i; + + if ((p = party_search(party_id)) == NULL) { + ShowWarning("buildin_foreachinparty: Party id '%d' doesn't exist or is not loaded yet.\n", party_id); + return SCRIPT_CMD_SUCCESS; + } + + for (i = 0; i < MAX_PARTY; ++i) { + TBL_PC* sd; + int char_id = p->party.member[i].char_id; + + if (char_id == 0 || (sd = map_charid2sd(char_id)) == NULL) + continue; + + script_foreach_sub(sd, event); + } + + return SCRIPT_CMD_SUCCESS; +} + +/// foreachinarea "<npc_label>", "<map_name>", <x1>, <y1>, <x2>, <y2> +BUILDIN_FUNC(foreachinarea) +{ + const char* event = script_getstr(st, 2); + const char* mapname = script_getstr(st, 3); + int x1 = script_getnum(st, 4); + int y1 = script_getnum(st, 5); + int x2 = script_getnum(st, 6); + int y2 = script_getnum(st, 7); + TBL_NPC* nd = map_id2nd(st->oid); + int16 m = (nd && strcmp(mapname, "this") == 0) ? nd->bl.m : map_mapname2mapid(mapname); + + if (m < 0) { + ShowWarning("buildin_foreachinarea: Invalid map name '%s'.\n", mapname); + return SCRIPT_CMD_SUCCESS; + } + + map_foreachinarea(script_foreach_sub_va_bl, m, x1, y1, x2, y2, BL_PC, event); + return SCRIPT_CMD_SUCCESS; +} + +/// foreachinshootablerange "<npc_label>", "<map_name>", <x>, <y>, <range> +BUILDIN_FUNC(foreachinshootablerange) +{ + const char* event = script_getstr(st, 2); + const char* mapname = script_getstr(st, 3); + struct block_list bl; + int x1 = script_getnum(st, 4); + int y1 = script_getnum(st, 5); + int range = script_getnum(st, 6); + TBL_NPC* nd = map_id2nd(st->oid); + int16 m = (nd && strcmp(mapname, "this") == 0) ? nd->bl.m : map_mapname2mapid(mapname); + + if (m < 0) { + ShowWarning("buildin_foreachinarea: Invalid map name '%s'.\n", mapname); + return SCRIPT_CMD_SUCCESS; + } + + memset(&bl, 0, sizeof(struct block_list)); + bl.m = m; + bl.x = x1; + bl.y = y1; + + map_foreachinshootrange(script_foreach_sub_va_bl, &bl, range, BL_PC, event); + return SCRIPT_CMD_SUCCESS; +} + +/// foreachinguild "<npc_label>", <guild_id> +BUILDIN_FUNC(foreachinguild) +{ + const char* event = script_getstr(st, 2); + int guild_id = script_getnum(st, 3); + struct guild* g; + int i; + + if ((g = guild_search(guild_id)) == NULL) { + ShowWarning("buildin_foreachinguild: Guild id '%d' doesn't exist or is not loaded yet.\n", guild_id); + return SCRIPT_CMD_SUCCESS; + } + + for (i = 0; i < MAX_GUILD; ++i) { + TBL_PC* sd; + + if (!(sd = g->member[i].sd)) + continue; + + script_foreach_sub(sd, event); + } + + return SCRIPT_CMD_SUCCESS; +} /*========================================== * @@ -24642,6 +24786,13 @@ struct script_function buildin_func[] = { BUILDIN_DEF2(round, "floor", "i"), BUILDIN_DEF(getequiptradability, "i?"), BUILDIN_DEF(mail, "isss*"), + + BUILDIN_DEF(foreachinserver, "s"), + BUILDIN_DEF(foreachinmap, "ss"), + BUILDIN_DEF(foreachinparty, "si"), + BUILDIN_DEF(foreachinarea, "ssiiii"), + BUILDIN_DEF(foreachinshootablerange, "ssiii"), + BUILDIN_DEF(foreachinguild, "si"), #include "../custom/script_def.inc" {NULL,NULL,NULL}, foreach.diff
    1 point
  2. Use doevent instead of donpcevent to keep the RID attached !
    1 point
  3. Is this map insipired from Descendants of the Sun movie ?
    1 point
  4. Updooted, nice guide. Edit: Here's a mirror for roBrowser's source code. https://mega.nz/#!d08QhDZI!yyDlaLesimL0zHSAlb1tJCWptB8YrFAh5XWeCyTtdJw SHA1: 2d8de69774442210cc7768c2aaf81cd49cbd5238 SHA256: c610180aac7f6ceb3e062d21ee951cd0db2bb1da2e2c4fee366b61f6432f1c25 MD5: 95ce6c6e9ec31e95838fca6746ecb5e1
    1 point
  5. The Best RO Template Map Ever Made This is the best RO template map in the world, and the only one that you will ever need to use, for every single map you will ever make. I made this template sometime in early to mid 2012 and have used it on every single map I've made since. You might be asking yourself why this is so much better than taking an existing RO map and using the 'Clear Map' function like a chump, so I'll run down a list of reasons why this template is better than every other template you might already be using. It's really big. This is a 200x200 map template. It's as big as the biggest field/town maps in RO. You won't always need to use all of that space, but why start mapping on a smaller map and run out of room when you can map on the biggest possible map size and just make your leftover space invisible tiles? It provides a 4x4 grid for placing textures. The vast majority of ground textures in RO are scaled to be placed down at 4x4 tiles (or 8x8 cells ingame) in size. The entire map is arranged in a convenient grid so that you can place textures down according to this size, and then deviate from the grid to make things look better without fear of breaking symmetry or getting things misaligned. The center is easily identifiable. A grass texture has been placed in the center of the map, and two small black squares have been placed at the map edges lining up with the center. If you want to create multiple field maps that connect to one another seemlessly, this makes it very easy to do that. You can make all sorts of measurements that will help you in planning your map and scaling things, as well. This combined with the grid makes it easy to plan/scale everything from the moment you start mapping. You can quickly replace the entire map with a ground texture. Scroll down through the textures on the map and select the second black texture, just below the dirt texture. It looks like this. Open the texture select window, and shift+click the texture you want to fill the map. It'll replace all the black squares on the map (except those 1x1 squares at the edges) with your ground texture of choice. This means you don't need to waste 5 minutes filling your forest map with grass textures like some sort of inefficient gorilla. You can customize it however you want. I have a few variations of this template map I keep for my own use, with model sets that I can duplicate easily. (Like trees or boats or houses made up of many smaller objects.) If you're making many maps that all have something similar in them, you can save another copy of this template with whatever you want loaded on there. You can download this map by clicking Here. Frequently Asked Questions Why are there a bunch of Prontera/Sograt textures on the list? I made this in 2012 and never bothered getting rid of them. Deal with it.
    1 point
  6. yes it is possible @maxine02 here the step @norirag 1. just create github page, 2. upload thor patcher file , config it like always 3. because thor patcher does not support https (default domain github page always use https) so you need to use custom domain, register some free domains, .tk .ml or what so ever and change the nameserver to use github page DNS, 4. upload the patcher file, 5. then try update your client using thor patcher
    1 point
×
×
  • Create New...