Jump to content

Tokei

Members
  • Posts

    658
  • Joined

  • Last visited

  • Days Won

    89

Everything posted by Tokei

  1. The separator used for menus is the colon, ":". So just change "%" to "%:". Though, this line: .@part = .@count[select(.@menu$)]; doesn't make a whole lot of sense. Keep in mind that select returns the first value as 1 instead of 0, so you have to remove 1. What you probably wanted to write was the following. .@selected = select(.@menu$) - 1; .@itemid = .@item[.@selected]; Also, not... an issue, but you'd probably want to change your variable names a bit by adding an 's' to your arrays otherwise it becomes very messy (and addding [0] is redundant). copyarray .@items, $@MobDrop_item, .@count; Also, might as well use sprintf for your drop rates, it makes your life easier. So something like this: mes "Monster ID: "+getmonsterinfo(.@mob_id,MOB_NAME)+"'"; if (getmobdrops(.@mob_id)) { // 'getmobdrops' returns 1 on success // immediately copy global temporary variables into scope variables, // since we don't know when 'getmobdrops' will get called again for // another mob, overwriting your global temporary variables .@count = $@MobDrop_count; copyarray .@items, $@MobDrop_item, .@count; copyarray .@rates, $@MobDrop_rate, .@count; mes getmonsterinfo(.@mob_id,MOB_NAME) + " - " + .@count + " drops found:"; for (.@i = 0; .@i < .@count; .@i++) { .@menu$ = .@menu$ + sprintf("%d (%s) %d.%02d%%", .@items[.@i], getitemname(.@items[.@i]), .@rates[.@i] / 100, .@rates[.@i] % 100) + ":"; } .@menu$ = .@menu$ + ":"; } else { mes "Unknown monster ID."; } .@selected = select(.@menu$) - 1; .@item = .@items[.@selected]; .@rate = .@rates[.@selected];
  2. Hmm, well I was able to make it into a flat map without any issues? Make sure you are using the latest version in the description.
  3. That usually means you're missing a VC++ library, though I don't remember which one it was compiled on. I'm guessing it's most likely VC++ 2010 (maybe 2008 as well). I'm guessing you picked x64 instead of x86 though.
  4. Heya, Unfortunately, that is not really possible. The gif format doesn't support semi-transparency. One pixel color can be transparent (which is commonly the pink color in RO, or 0xff00ff). While... this is possible to support, it would also make any other semi-transparent pixel look horrible with shades of pink for any of your other semi-transparent layers (I'd show you an example, but I'm on phone right now). It's a limitation of the gif format, there's not much I can do there. That's why I didn't really bother with transparency support while saving gif images and instead opted of rendering the str as they are directly shown in the preview window. I would suggest simply changing the background to black to make these gifs as this is when you'll have the best output. Alternatively, you could change the background color to wherever you plan on displaying these gifs, but you'll quickly see white background isn't a great choice for most str. Saving those animations is just really troublesome. The only real "solution" I could come up with is saving the output as a series of PNG images (which I'm not sure is actually possible, but worth looking into). Though, that wouldn't really solve what you're trying to do, at least I don't think...?
  5. Heya, You can create a new script command: static int buildin_killmonsterarea_sub(struct block_list *bl,va_list ap) { int x1 = va_arg(ap, int); int y1 = va_arg(ap, int); int x2 = va_arg(ap, int); int y2 = va_arg(ap, int); if (x1 <= bl->x && bl->x <= x2 && y2 <= bl->y && bl->y <= y1) status_kill(bl); return 0; } BUILDIN_FUNC(killmonsterarea) { const char *mapname; int16 m; int x1, x2, y1, y2; mapname=script_getstr(st,2); if( (m = map_mapname2mapid(mapname))<0 ) return 0; x1=script_getnum(st,3); y1=script_getnum(st,4); x2=script_getnum(st,5); y2=script_getnum(st,6); map_foreachinmap(buildin_killmonsterarea_sub,m,BL_MOB, x1, y1, x2, y2); return SCRIPT_CMD_SUCCESS; } // def BUILDIN_DEF(killmonsterarea,"siiii"),
  6. GRF encryption isn't restricted by client version. It works on any.
  7. I am not able to reproduce this issue. Str files do not have a bias value to begin with though, that's emulated. If the bias value isn't showing up, it could be that it simply failed to guess the value properly. Either way, I would need an example (with a file if possible) on how to reproduce. As for the second part, at 0x10c, the value should indeed be 0x00000000. That is the delay for texture animation. That value, "0x7f800000", means "Infinifty" which is usually the result of a division by 0. That's... a bug with the original str file. I saw it in your EZV file and I fixed the output to say "0" instead as it didn't make any sense to save the value as "Infinity" in a EZV file. As for the str file itself, it has no impact since the animation type is set to normal, and therefore the value isn't read at all. I will make a small change however and make sure this value (infinity) can't propagate anywhere either and fix it when loading the str file instead. I'll wait for more information on the bias issue above though.
  8. Heya, I see what you mean now; it should be fixed in 1.0.7.
  9. Well, as the error says: the file is empty (0 byte).
  10. Hmm, I'm not able to reproduce your issue. Saving as ezv works fine on my end. I have uploaded a newer version (1.0.6) to save ezv as 0.95 instead of 0.94 to support tga images. But that doesn't appear to be related to your issue at all, so you'd have to give me a way to reproduce the problem.
  11. Updated to 1.8.4.5: Fixed a bunch of issues with the dark theme. Fixed focussing in the tree view. Added Str preview support. Added support for RSW version 0x206. Fixed another packed DLL issue regarding GRF encryption. Extracting resources will now export all files. Added more checks when saving GRFs beyond 4 GB. I've added a "fix" for this issue, but like I said last time, it isn't an issue. GRF Editor will now prevent you from saving files past 4 GB of size. If your GRFs are reaching that size, you will need to use another GRF alongside for your client. There are no other solutions. Should be fixed now.
  12. Heya, Sorry about this! I have re-uploaded with the same link as above. It appears one of the library didn't compress properly when packing the executable.
  13. Updated to 1.8.4.3 : Added support for json and bson file formats (you can save as a bson file after editing). Only common types are supported. Fixed a bug with the lub decompiler regarding non-latin strings not being enclosed properly.
  14. It's failing to save the file because you have the file opened in GRF Editor already. You can't write/modify a file that's being used by another program. So as the error says, the file is locked.
  15. The client can read up to uint32, so ~4GB. But you are indeed correct, GRF Editor shouldn't allow more than that either for obvious reasons. Though the check put in place for size limit is obviously not working, so I'd have to fix that.
  16. Heya, A few comments first: I assume that this script is going to be duplicated since you have multiple copies of it in your replay. I made it into a floating script instead. There are no handy methods to use for making a character walk towards a target with 1 cell distance (it will try to go on top of the target). If you want something more convenient, you'll have to use unitwalk with x/y coordinates, or make your own function. Though for a starting script, unitwalkto will do. Since you can break the script by simply walking away, while unitwalkto is running, it will trigger the OnOpenChest event label for some unknown reason. So you need to check the distance again. Plus, by doing so, you also prevent other type of exploits like using close confine. I added an ID next to the NPC name (World Boss Treasure#ID), which is used to prevent another exploit: If two players talk to the treasure at the same time, they'll both be able to get the items from the treasure box, whether or not you disabled the NPC. NPC variables (those starting with a .) are shared among all the duplicated NPCs. That's why I use an unique ID to track whether the box was already looted or not. - script World Boss Treasure#wb 1324,{ getmapxy(.@map$, .@npc_x, .@npc_y, 0); getmapxy(.@map$, .@player_x, .@player_y, 1); .@distance = distance(.@npc_x, .@npc_y, .@player_x, .@player_y); if (.@distance > 1) { unitwalkto getcharid(3), getnpcid(0), strnpcinfo(0) + "::OnOpenChest"; end; } goto OnOpenChest; end; OnOpenChest: getmapxy(.@map$, .@npc_x, .@npc_y, 0); getmapxy(.@map$, .@player_x, .@player_y, 1); .@distance = distance(.@npc_x, .@npc_y, .@player_x, .@player_y); if (.@distance > 1) { end; } progressbar "ffff00", 10; .@id = atoi(strnpcinfo(2)); // I presume you don't want multiple people to loot the same chest...? if (.npc_disabled[.@id]) { //dispbottom "This chest has been looted by someone else!"; end; } specialeffect EF_COIN; .wb_treasure[.wb_treasure_size++] = getcharid(3); setarray .@catch, 30203, 30202, 607, 504; // List of Junk/Other getitem .@catch[rand(getarraysize(.@catch))], 1; disablenpc strnpcinfo(0); .npc_disabled[.@id] = true; initnpctimer; end; OnReward: .@id = atoi(strnpcinfo(2)); .npc_disabled[.@id] = false; deletearray .wb_treasure; enablenpc strnpcinfo(0); initnpctimer; end; OnTimer7200000: disablenpc strnpcinfo(0); stopnpctimer; end; } prontera,150,180,3 duplicate(World Boss Treasure#wb) World Boss Treasure#1 1324 prontera,152,180,3 duplicate(World Boss Treasure#wb) World Boss Treasure#2 1324
  17. The simplest way to do that is via a status effect. You give the status when the player uses @pk, and when the status runs out, it removes the pk mode. int atcommand_pkmode( const int fd, struct map_session_data *sd, const char *command, const char *message ) { nullpo_retr(-1, sd); if (!sd->state.pk_mode) { sd->state.pk_mode = 1; sc_start(&sd->bl, &sd->bl, SC_PK_DISABLE, 100, 0, 60 * 60 * 10000); clif_displaymessage(sd->fd, "You are now no longer in PK mode."); } else { sd->state.pk_mode = 0; status_change_end(&sd->bl, SC_PK_DISABLE); clif_displaymessage(sd->fd, "Returned to normal state."); } return 0; } And define the SC_PK_DISABLE status: diff --git a/db/re/status.yml b/db/re/status.yml index 96693fdce..40693394c 100644 --- a/db/re/status.yml +++ b/db/re/status.yml @@ -8166,3 +8166,9 @@ Body: NoClearbuff: true End: Sub_Weaponproperty: true + - Status: Pk_Disable + #Icon: EFST_PK_DISABLE + Flags: + NoDispell: true + NoBanishingBuster: true + NoClearance: true diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index 25ce19a67..ddbd1c466 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -1844,6 +1844,7 @@ export_constant(SC_M_LIFEPOTION); export_constant(SC_S_MANAPOTION); export_constant(SC_SUB_WEAPONPROPERTY); + export_constant(SC_PK_DISABLE); #ifdef RENEWAL export_constant(SC_EXTREMITYFIST2); diff --git a/src/map/status.cpp b/src/map/status.cpp index 42005bdae..4b6f462fb 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -13351,6 +13351,11 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid) pc_delabyssball( *sd, sd->abyssball ); } break; + case SC_PK_DISABLE: + if (sd) { + sd->state.pk_mode = 0; + } + break; } // Reset the options as needed diff --git a/src/map/status.hpp b/src/map/status.hpp index f103cd018..f2b79e058 100644 --- a/src/map/status.hpp +++ b/src/map/status.hpp @@ -1230,7 +1230,7 @@ enum sc_type : int16 { SC_S_MANAPOTION, SC_SUB_WEAPONPROPERTY, - + SC_PK_DISABLE, #ifdef RENEWAL SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled #endif (Also... shouldn't this message "You are now no longer in PK mode." be "You are now in PK mode." instead?)
  18. Change the query to do just that, and reverse the output displayed to the player. .@count = query_sql("SELECT `time`,`name`,`nameid`,`amount` FROM `guild_storage_log` WHERE `guild_id` = '" + getcharid(2) + "' ORDER BY `id` DESC LIMIT 30", .@time$ ,.@name$,.@item_id,.@amount); if(!.@item_id){ mes "there is no log yet"; close; } dispbottom "=========================================================",0xFFD64F; dispbottom "===================== Guild Storage Log =======================",0xFFD64F; dispbottom "=========================================================",0xFFD64F; for(.@i=.@count-1;.@i>=0;.@i--) dispbottom .@time$[.@i] + " Player[" + .@name$[.@i] + "] Item Name[" + getitemname(.@item_id[.@i]) + "] Item Amount[" + .@amount[.@i] + "]",((.@amount[.@i] > 0)?0x03c6fc:0xFF0000); dispbottom "=========================================================",0xFFD64F; Though...! At this point, why not simply use the script command guildopenstorage_log ? It sounds like it does exactly what you want to do with an UI in-game as well. You'd have to change the constant MAX_GUILD_STORAGE_LOG_PACKET to const int16 MAX_GUILD_STORAGE_LOG_PACKET = 30;
  19. It seems like the client is able to connect to the login-server, but is not able to connect to the char-server. Assuming you have no errors showing up in any of your console, have you... tested if the port 5800 is open on VM#2, on 10.1.1.2? That would be my guess. https://www.yougetsignal.com/tools/open-ports/
  20. Ah, I misunderstood your issue, my bad. The resurrection skill is blocked if your PVP points are below zero, which happens everytime you die too often in PVP. Change the condition in skill.cpp for the "case ALL_RESURRECTION:" diff --git a/src/map/skill.cpp b/src/map/skill.cpp index b48373392..f19c80142 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -7170,7 +7170,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; } - if (map_getmapflag(bl->m, MF_PVP) && dstsd && dstsd->pvp_point < 0) + if (map_getmapflag(bl->m, MF_PVP) && dstsd && dstsd->pvp_point < 0 && !map_getmapflag(bl->m, MF_MAPMVP)) break; switch(skill_lv){
  21. Hmm, can you show the flags of the map with "@mapflag"? There aren't many possible issues left beyond the ones posted above, so you'll probably need to set a breakpoint to see what is going on directly.
  22. Did you correctly apply the diff file? - if( sd->pvp_point < 0 ) { + if( sd->pvp_point < 0 && !mapdata->flag[MF_MAPMVP] ) { sd->respawn_tid = add_timer(tick+1000, pc_respawn_timer,sd->bl.id,0); return 1|8; } This is the part that respawns a character when they die on a PVP map. So a few possible options here: Your map doesn't have the mapmvp flag (MF_MAPMVP). You do need to add those manually. You can see if the map has the mapflag with @mapflag while in-game. The code "!mapdata->flag[MF_MAPMVP]" wasn't added to the pc_dead function from the diff file. You didn't recompile your server.
  23. Heya, The original script can be opened with Scripts > Open scripts folder > script5_remove_unused_sprites.cs. In your case, you'd want something like this: foreach (var actPath in Directory.GetFiles(@"C:\Test\", "*.act")) { var sprPath = actPath.ReplaceExtension(".spr"); if (!File.Exists(sprPath)) continue; var actFile = new Act(actPath, sprPath); for (int i = actFile.Sprite.Images.Count - 1; i >= 0; i--) { if (actFile.FindUsageOf(i).Count == 0) { actFile.Sprite.Remove(i, actFile, EditOption.AdjustIndexes); } } actFile.SaveWithSprite(actPath, sprPath); }
×
×
  • Create New...