Jump to content

meko

Core Developers
  • Content Count

    363
  • Joined

  • Days Won

    46

Posts posted by meko


  1. Update: September 19 2017

     

    Projects merged:

     

    New script commands:

     

    Modified script commands:

     

    Deprecated script commands:


  2. As of September 18 2017, the useatcmd() command has been deprecated.



    If you were using useatcmd() for built-in @commands you can simply replace it with atcommand():

    useatcmd("@command") ➜ atcommand("@command")

     

     

    If you were using useatcmd() for custom @commands (registered with bindatcmd()) you can use doevent() instead:

    useatcmd("@custom") ➜ doevent("MyNPC::OnUseCommand");

    MyNPC is the name of the NPC in which you used bindatcmd()
    OnUseCommand is the event you registered with bindatcmd()

     


    Edge cases:
    useatcmd(), unlike atcommand(), uses the group id of the attached player rather than running with admin privileges. If you need to check whether or not a player should be able to use a command, use can_use_command()

    if (can_use_command("@foobar")) {
    	atcommand("@foobar");
    } else {
    	dispbottom("You cannot use this command!");
    }

     


  3. As of June 3rd, the pow() command has been superseded by the exponentiation operator (**). You can still use pow() but it will trigger a warning every time, as this command will be removed in the future.

     

    The exponentiation operator has higher precedence than any other operator.

    This means (a * b ** c) is equivalent to (a * (b ** c)) and not ((a * b) ** c)

     

     

     

    Here's how to migrate your scripts:

     

    pow(a, b) ➜ (a ** b)

     

     

    In combination with other operators:

     

    pow(a * b, c) ➜ ((a * b) ** c)

    pow(a, b * c) ➜ (a ** (b * c))

     

     

     

    To automatically convert your scripts:

    # from the Hercules root folder:
    find npc db -type f -exec sed -i -r 's/pow\((.+),[ ]*(.+)\)/((\1) ** (\2))/g' {} +

     

     

    If you are using vanilla Hercules then all your scripts should already be converted.

    See also http://herc.ws/board/topic/14848-deprecation-specialeffect2-misceffect/


  4. As of June 3rd, the specialeffect() command has been upgraded and it now allows to use effects on any kind of unit (player, npc, mob, homunculus, ...) and to show it to any player. This allowed us to deprecate specialeffect2() and misceffect() so now there is a single command for effects instead of 3 different ones, making things simpler for everyone. You can still use specialeffect2() and misceffect() but they will trigger a warning every time, since they will be removed in the future.

     

    Here's how the updated specialeffect() command works:

     

    specialeffect(effect number{, send target{, unit id{, account id ]}})

     

    effect number is the effect to use.
    see effect_list.txt for a list of all effects

     

    send target is to whom the effect should be sent. The most common values are:

    AREA will show the effect to every player in the area
    SELF will show the effect to one player only

    see constants.md for a list of possible send targets

     

    unit id is the unit on which the effect should be centered
    it can be a mob id, an account id, a npc id or the id of any other kind of unit

     

    account id is the player to which the effect should be sent if SELF was specified as send target

     

    To migrate from specialeffect2 to specialeffect:
     

    specialeffect2(effect) ➜ specialeffect(effect, AREA, playerattached())


    specialeffect2(effect, target, "player name") ➜ specialeffect(effect, target, getcharid(CHAR_ID_ACCOUNT, "player name"))

     

    To migrate from misceffect to specialeffect:

    Because the behaviour of this command varies depending on if the npc has a sprite or not, what you want is either one of the two:


    misceffect(effect) ➜ specialeffect(effect)

    misceffect(effect) ➜ specialeffect(effect, AREA, playerattached())


  5. Hi there, I refactored your script

    rothyr,210,146,4	script	Styliste#rot	2_M_DYEINGER,{
    
    	function changeSingleStyle {
    		.@backup = getlook(getarg(0));
    		.@current = getarg(1);
    
    		do {
    			setlook(getarg(0), .@current);
    			mesf("C'est le style #%i.", .@current);
    
    			select((.@current + 1) <= getarg(2) ? "Suivant" : "",
    				(.@current - 1) >= getarg(1) ? "Précédent" : "",
    				"Aller à...",
    				.@current > getarg(1) ? "Aller au début" : "",
    				.@current < getarg(2) ? "Aller à la fin" : "",
    				"Parfait!",
    				"Annuler!");
    
    			switch (@menu) {
    			case 1: ++.@current; break;
    			case 2: --.@current; break;
    			case 3: input(.@current, getarg(1), getarg(2)); break;
    			case 4: .@current = getarg(1); break;
    			case 5: .@current = getarg(2); break;
    			case 7: setlook(getarg(0), .@backup); // fallthrough
    			case 6:
    				mes("Ok, c'est fait.");
    				mes("Besoin d'autre chose?");
    				next();
    				return;
    			}
    		} while (true);
    	}
    
    	function changeAllStyles {
    		setarray(.@backup[0], getlook(LOOK_HAIR), getlook(LOOK_HAIR_COLOR), getlook(LOOK_CLOTHES_COLOR));
    
    		do {
    			if (getarg(0)) {
    				setlook(LOOK_HAIR, rand(.min_style, .max_style));
    				setlook(LOOK_HAIR_COLOR, rand(.min_color, .max_color));
    				setlook(LOOK_CLOTHES_COLOR, rand(.min_cloth, .max_cloth));
    			} else {
    				mes("Veuillez entrer le N° de couleur de vêtement:");
    				input(.@i, .min_cloth, .max_cloth);
    				setlook(LOOK_CLOTHES_COLOR, .@i);
    
    				mes("Veuillez entrer le N° de style de cheveux:");
    				input(.@i, .min_style, .max_style);
    				setlook(LOOK_HAIR, .@i);
    
    				mes("Veuillez entrer le N° de couleur de cheveux:");
    				input(.@i, .min_color, .max_color);
    				setlook(LOOK_HAIR_COLOR, .@i);
    			}
    
    			mesf("Vous avez présentement la coupe #%i de couleur #%i, avec des vêtements de couleur #%i.",
    				getlook(LOOK_HAIR), getlook(LOOK_HAIR_COLOR), getlook(LOOK_CLOTHES_COLOR));
    
    			select("Recommencer",
    				"Parfait!",
    				"Annuler!");
    
    			switch (@menu) {
    			case 3:
    				setlook(LOOK_HAIR, .@backup[0]);
    				setlook(LOOK_HAIR_COLOR, .@backup[1]);
    				setlook(LOOK_CLOTHES_COLOR, .@backup[2]);
    			case 2: return;
    			}
    		} while (true);
    	}
    
    	cutin("job_alche_vincent", 2);
    	mesf("[ %s ]", strnpcinfo(NPC_NAME));
    
    	// OnClick
    	mes("Bonjour, que puis-je faire pour vous?");
    	next();
    
    	do {
    		mesf("Vous avez présentement la coupe #%i de couleur #%i, avec des vêtements de couleur #%i.",
    			getlook(LOOK_HAIR), getlook(LOOK_HAIR_COLOR), getlook(LOOK_CLOTHES_COLOR));
    
    		select("Couleur de vêtement",
    			"Coupe de cheveux",
    			"Couleur de cheveux",
    			"Tout changer d'un coup",
    			"Au hasard",
    			"Quitter");
    
    		switch (@menu) {
    		case 1:
    			changeSingleStyle(LOOK_CLOTHES_COLOR, .min_cloth, .max_cloth);
    			break;
    		case 2:
    			changeSingleStyle(LOOK_HAIR, .min_style, .max_style);
    			break;
    		case 3:
    			changeSingleStyle(LOOK_HAIR_COLOR, .min_color, .max_color);
    			break;
    		case 4:
    			changeAllStyles(false);
    			break;
    		case 5:
    			changeAllStyles(true);
    			break;
    		default:
    			close;
    		}
    	} while (true);
    
    OnInit:
    	.min_style = max(1, getbattleflag("min_hair_style"));
    	.max_style = getbattleflag("max_hair_style");
    	.min_color = max(1, getbattleflag("min_hair_color"));
    	.max_color = getbattleflag("max_hair_color");
    	.min_cloth = max(1, getbattleflag("min_cloth_color"));
    	.max_cloth = getbattleflag("max_cloth_color");
    }

    Down from 326 lines to just 121 lines, while still preserving functionality and while avoiding the goto spaghetti


  6. phpmyadmin has nothing to do with linux users; it is a tool to administer your sql databases

    also Hercules does not ship pre-built binaries so just checkout another commit and compile it, but since you are trying to do this only to run Hercules as root I would highly discourage doing so


  7. First of all, please tell us what error you encounter while compiling the most recent version of Hercules, this way we can fix it.


    If you absolutely must use an older version then you will have to clone the repository using git clone and then check out an older commit (any commit) using git checkout:

    git clone https://github.com/HerculesWS/Hercules.git
    cd Hercules
    git checkout abcdef0

    replace abcdef0 with the sha1 hash of the commit you wish to use


  8. You do this through SSH, not a web-based control panel (although it might have that feature, not sure).

    You have to generate a SSH key and add it to your host, then open a terminal and connect to the host using your key.
    If your web-based control panel has a built-in terminal emulator you could use that too


  9. Hercules does not have a command to put items directly in storage so just use getitem/getitem2 and remove the storeitem/storeitem2. The use of checkweight guarantees it can be put in the inventory so you don't need to mess with storage anyway


  10. Also, don't forget to check if the item can be carried by the player:

    if (countitem(501) >= 1) {
    	mes("you have the requested item");
    	if (!checkweight(502, 1)) {
    		mes("...but you can't carry it!");
    	} else {
    		delitem(501, 1);
    		getitem(502, 1);
    	}
    } else {
    	mes("you don't have anything");
    }
    
    close;

    And instead of 501 / 502 you should use constants


  11. The more operation you do the longer the thread blocks. Look out for long loops or scripts going through lots of labels or doing expensive computations (such as hashing). If you want to hunt down the culprits then search for those commands: freeloop, sleep, md5. parsing regular expressions can also be quite costly if the pattern is complex.

     

    As for network lag, keep in mind that the farther away you are from the server the longer it takes for packets to reach you. Even if the networks between you and the server were entirely fiber-optics from end to end (unlikely) you would still experience lag since light travels at a finite speed and the more nodes the traffic goes through the longer it takes. Once it reaches your local network the router has to decide to which device to send the packets, and once it reaches your pc it, too, needs to decide to which software to send it. There is some processing involved in every step and this is not instantaneous. Your users will also experience more lag if they use wireless or satellite connections and even more if their PC is slow.

     

    No matter what you do there will always be lag, but you can make it more bearable by having multiple servers spread accross the world, like having an American server, an European server and an Asian server.

     

    Lifewire has a great article about this: https://www.lifewire.com/lag-on-computer-networks-and-online-817370


  12. The short answer is

    UPDATE `char`
    INNER JOIN (SELECT @row := MAX(`char_id`) FROM `char`) r
    SET `char`.`char_id` = @row := @row + 1
    WHERE `char`.`char_id` < 150000

    But you also need to update all tables that uses char id, and I don't have the patience to write such a long SQL query. A simpler approach would be to check how many chars are below 150000 and just delete those chars and re-create them


  13. 9 minutes ago, Jeffery said:

    Another usage,

    
    	function	test_f	{
    		copyarray .@new_array,getarg(0),getarraysize(getarg(0));
    		
    		dispbottom .@new_array[0]; // --> 10
    		dispbottom .@new_array[1]; // --> 20
    		dispbottom .@new_array[2]; // --> 30
    		dispbottom .@new_array[3]; // --> 40
    		dispbottom .@new_array[4]; // --> 50
    		
    		return;
    	}
    	
    	setarray .@array,10,20,30,40,50;
    	
    	test_f(.@array);

     

    this is a horrendous way to do it; instead of duplicating the array you should access directly with getelementofarray(getarg(0), index)

     

    see this file for more examples: 

     

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.