-
Content Count
363 -
Joined
-
Days Won
46
Posts posted by meko
-
-
// 1 / 20 chance => 5%
if (rand(20) == 0) {
getitem(...); // give the item
}
else {
// do something else
}
-
not sure clone() is a good idea, because it requires the cloned player to be online, but if that's intended then try this:
.@mobGID = clone("prontera", 157, 167, "HALL::OnMobDead", 150005, 0, 0x0); // make the clone setunitdata(.@mobGID, UDT_MODE, getunitdata(.@mobGID, UDT_MODE) &~ (1 | 128)); // prevent from attacking & moving
this makes it unable to move or attack, but doesn't (and can't) prevent the player from attacking it
An alternative could be to use a NPC instead and change its appearance by manipulating UDT_SEX, UDT_HAIRSTYLE, UDT_HAIRCOLOR, UDT_HEADBOTTOM, UDT_HEADMIDDLE, UDT_HEADTOP, UDT_CLOTHCOLOR, UDT_SHIELD, and UDT_WEAPON, but I don't know if the Gravity client supports dynamic NPCs
-
I think the only way to selectively hide a npc would be to make map instances but that adds a layer of complexity for nothing imho. You could just make your merchant say stuff like "I'm busy, don't bother me" if the criteria is unmet, and else call the shop menu
-
Actually it's pretty useful, it allows to pass custom variables instead of having the functions register hardcoded variables, and it avoids having to use getd. So if your function needs to return more than one value it can just ask for a variable as an argument, and fill it with the return data. The alternative would be to implode() the values, return, and then explode() after the function call, which is much dirtier.
-
It's impossible to have perfect RNG without natural entropy. You'd need a hardware generator for that, and even then they're not always perfect
-
if all you want to do is drop an item, this can be done directly in the mob db
about rand() you cannot use a custom seed; Hercules generates its own
With killedrid you could get the mob id with getunitdats(UDT_CLASS, killedrid) and then you can get further information with getmonsterinfo()
-
setarray() does not create the structure of the array; it sets multiple elements of the array at the same time.
this means every time setarray() is called it will overwrite the values.
arrays do not need to be declared. every variable is always implicitly an array
Also, there's another problem: variable$[2] = 1;
You are setting an integer as value of a string variable
If what you need is an array of integers then remove the "$" in the variable name
-
it's not possible to make it persist after logout, but you can emulate this behaviour by setting a char variable, then in OnPCLoginEvent checking if the variable exists and calling atcommand()
-
I do see your problem though:
if (.@mapa$ != "pvp_n_1-5,guild_vs2,pvp_n_1-3")
Here you are checking for a map called "pvp_n_1-5,guild_vs2,pvp_n_1-3", not for 3 different maps.
Try replacing by:
if (.@mapa$ != "pvp_n_1-5" && .@mapa$ != "guild_vs2" && .@mapa$ != "pvp_n_1-3")
-
first, remove the existing drop:
delmonsterdrop(<mob id or name>, <item id>)
then add it back, with a different drop rate:
addmonsterdrop(<mob id or name>, <item id>, <rate>)
This will only change one monster at a time, so you must hard-code all the mob ids in your script.
An alternative could be to iterate over ALL monsters in a loop starting from id 1001 and checking with getmonsterinfo() if the race is RC_Fish, but the loop would be insanely long and block the thread (so requires freeloop), which would make the server completely unresponsive while processing the loop. If you only plan to do it in OnInit or when a custom atcommand is called it would probably be fine though.
-
When a function is invoked, the arguments are pushed to the stack, but if an argument is a scope variable its reference is also pushed. This means you can access variables of the parent scope from within a function.
function do_something { setarray(getarg(0), 69, 42, 1337); return; } debugmes(.@var[0]); // <= 0 debugmes(.@var[1]); // <= 0 debugmes(.@var[2]); // <= 0 do_something(.@var[0]); debugmes(.@var[0]); // <= 69 debugmes(.@var[1]); // <= 42 debugmes(.@var[2]); // <= 1337
-
You spawn your monster like this:
.@mobGID = monster("prontera", 150, 150, "Poring", PORING, 1);
And you manipulate like this:
// to prevent from moving: setunitdata(.@mobGID, UDT_MODE, getunitdata(.@mobGID, UDT_MODE) &~ 1); // to prevent from attacking: setunitdata(.@mobGID, UDT_MODE, getunitdata(.@mobGID, UDT_MODE) &~ 128); // to change stats: setunitdata(.@mobGID, UDT_STR, 11); // <= change those numbers setunitdata(.@mobGID, UDT_AGI, 95); setunitdata(.@mobGID, UDT_VIT, 2); setunitdata(.@mobGID, UDT_INT, 55); setunitdata(.@mobGID, UDT_DEX, 10); setunitdata(.@mobGID, UDT_LUK, 40);
-
on line 22 just change "poring" to whatever name you want
same goes for "INVASION BOSS" on line 34
see https://github.com/HerculesWS/Hercules/blob/master/doc/script_commands.txt#L6072
-
the x1,y1,x2,y2 is the square area composed of the coordinates of the top-left tile and the bottom-right tile
Let's imagine a grid of x,y coordinates:
0,0 0,1 0,2 0,3 0,4
1,0 1,1 1,2 1,3 1,4
2,0 2,1 2,2 2,3 2,4
3,0 3,1 3,2 3,3 3,4
4,0 4,1 4,2 4,3 4,4
Let's say you want the coordinates in red to be basilica;
The top-left red tile is 1,1 in this case. This would be your x1,y1.
The bottom-right tile is 3,3. This would be your x2,y2
so you'd write setcell("map", 1,1, 3,3, cell_basilica, true)
If you do not know the coordinates you can simply walk to it with your character and use the @where command
-
you could spawn a mob then manipulate it with setunitdata()
as for where to get the data about the monster see getmonsterinfo()
-
try bonus2(bAddRace2, RC_All, 50) or bonus2(bMagicAtkEle, Ele_All, 50)
-
DropAnnounce is not enough, as it doesn't force pickup by the other player, and also it's only triggered on mob kill event, not pc
-
here's a rough draft (not tested)
- script PvP Ranking FAKE_NPC,{ OnPCKillEvent: pvp_rank[.this_week] += 3; // raise our own pvp rank dispbottom("You gain 3 points on PvP Rank"); attachrid(killedrid); pvp_rank[.this_week] = max(0, pvp_rank[.this_week] - 3); // decrease their pvp rank dispbottom("You received -3 points penalty on PvP Rank"); end; OnPCLoginEvent: OnClaimReward: .@char = getcharid(CHAR_ID_CHAR); if ($pending_badges[.@char] < 1) { end; } pvp_rank[$last_week] = 0; dispbottom(sprintf("PvP Rank: you obtained %i points this week, putting you at rank %i.", $pending_points[.@char], $pending_rank[.@char] + 1)); dispbottom(sprintf("Reward: %i badges.", $pending_badges[.@char])); getitem(Rok_Star_Badge, $pending_badges[.@char]); $pending_badges[.@char] = 0; $pending_points[.@char] = 0; $pending_rank[.@char] = 0; end; OnInit: .top_len = 10; // we want a top 10 // fallthrough OnSun0001: // every Sunday at 00:01 AM $last_week = .this_week; .this_week = atoi(gettimestr("%y%W", 4)); // YYWW if ($last_week < 1) { end; // this is our first week running this script } .@count = query_sql(sprintf("SELECT c.char_id, c.name, r.value" "FROM `char_reg_num_db` r " "JOIN `char` c ON r.char_id = c.char_id " "WHERE `key`='pvp_rank' AND `index`='%i' " "ORDER BY `value` DESC " "LIMIT " + .top_len + ";", $last_week), .top_char[0], .top_char$[0], .top_points[0]); // store that info so it can be reused throughout the week query_sql(sprintf("DELETE FROM `char_reg_num_db` WHERE `key`='pvp_rank' AND `index` <= %i", $last_week)); // janitor task for (.@i = 0; .@i < .@count; .@i++) { .@badges = (10 * .top_len) - (10 * .@i); // the badges this player won .@char = .top_char[.@i]; .@acc = charid2rid(.@char); $pending_badges[.@char] += .@badges; $pending_points[.@char] = .top_points[.@i]; $pending_rank[.@char] = (.@i + 1); if (.@acc > 0) { addtimer(rand(5000), "PvP Ranking::OnClaimReward", .@acc); } } end; }
You'll notice I did +3 and -3 for both killing and being killed; This is on purpose, else someone could just make 2 characters and kill each other to keep getting +1 every time (+3, -2)
To display the top 10 from last week in a npc you'd do something like:
mes("Here's the ranking for last week:"); next(); if (getvariableofnpc(.top_char[0], "PvP Ranking") < 1) { mes("(no ranking available for that week)"); next(); } .@max = getvariableofnpc(.top_len, "PvP Ranking"); for (.@i = 0; .@i < .@max; .@i++) { .@points = getvariableofnpc(.top_points[.@i], "PvP Ranking"); if (.@points < 1) { break; } mes(sprintf("%i. %s — %i points.", .@i + 1, getvariableofnpc(.top_char$[.@i], "PvP Ranking"), .@points)); next(); }
-
-
not sure if related but someone did request a script for a variable called "brokeemp", see http://herc.ws/board/topic/14684-can-some-one-convert-this-script-to-hercules/
-
add this mapflag: loadevent
then do something like:
OnPCLoadMapEvent: if (strcharinfo(PC_MAP) == "moc_fild22" && !@auth_moc_fild22) { warp("SavePoint", 0, 0); // player is not authorized to be on moc_fild22 } end;
and in the npc that warps the player to that map you'd just set @auth_moc_fild22 to true and warp to moc_fild22
-
.@count = query_sql("SELECT c.name, r.value AS points "
"FROM `char_reg_num_db` r "
"JOIN `char` c ON r.char_id = c.char_id "
"WHERE `key`='brokeemp' AND `index`='0' "
"ORDER BY `value` DESC "
"LIMIT 10;",
.@char$[0], .@points[0]);
for (.@i = 0; .@i < .@count; .@i++) {
mes(sprintf("%d. %s — %d points.", .@i + 1, .@char$[.@i], .@points[.@i]));
}
-
maybe something like this:
map,x,y,dir script npc name sprite,{ if (gettime(GETTIME_HOUR) == 15 || gettime(GETTIME_HOUR) == 19) { mes("I will now teleport you to the map."); close2(); // check the hour again, because the player can wait before closing if (gettime(GETTIME_HOUR) == 15 || gettime(GETTIME_HOUR) == 19) { warp(.dest_map$, .dest_x, .dest_y); addtimer(600000, strnpcinfo(NPC_NAME) + "::OnComeBack"); // 10 minutes end; } } mes("Sorry, I cannot teleport you right now."); next(); mes("Come back at 15H or 19H."); close; OnComeBack: warp("SavePoint", 0, 0); end; OnInit: .dest_map$ = "destination map"; .dest_x = 0; .dest_y = 0; // fallthrough OnHour16: OnHour20: // force any remaining player to come back if for whatever reason they are still there .@count = getunits(BL_PC, .@players, false, .dest_map$); for (.@i = 0; .@i < .@count; .@i++) { deltimer(strnpcinfo(NPC_NAME) + "::OnComeBack", .@players[.@i]); addtimer(0, strnpcinfo(NPC_NAME) + "::OnComeBack", .@players[.@i]); } end; }
-
maybe something like this:
OnPCKillEvent: if (rand(10) != 1) end; // artificial drop rate (1 in X chances to drop) delitem(Baphomet_Card, 1, killedrid); // force "drop" getitem(Baphomet_Card, 1); // force "pick-up" announce(sprintf("%s killed %s and obtained their Baphomet Card.", strcharinfo(PC_NAME), strcharinfo(PC_NAME, "unknown", killedrid)), bc_all); end;
Random area appearance of an NPC
in Script Support
Posted
I believe you wish the npc to spawn in random locations on the map?
For this you would first define your npc, then disable it in OnInit, and when the event starts you would enable it and move it to the desired location.
If this does not work for you then please attach your full script here