Jump to content

nitrous

Developer
  • Posts

    138
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by nitrous

  1. /**
     * questprogress(<ID>{,PLAYTIME|HUNTING{,<char_id>}})
     **/
    
    BUILDIN_DEF(questprogress, "i??"),
    BUILDIN_FUNC(questprogress)
    {
        struct map_session_data *sd;
        enum quest_check_type type = HAVEQUEST;
        int ret;
    
    
        if( script_hasdata(st, 3) )
            type = (enum quest_check_type)script_getnum(st, 3);
    
        if (!script_charid2sd(4,sd))
            return SCRIPT_CMD_FAILURE;
    
        ret = quest_check(sd, script_getnum(st, 2), type));
        if (ret == 0) ret = 1;
        if (ret == -1) ret = 0;
        script_pushint(st, ret);
    
        return SCRIPT_CMD_SUCCESS;
    }
    

    haven't tested it but it should work

  2. if ( Class==Job_High_wizard ){ bonus bDefRate,-50; bonus bDef2Rate,-50; bonus bInt,20; bonus bDex,20; bonus bVit,20; bonus2 bSkillAtk,"WZ_METEOR",35; bonus2 bSkillAtk,"WZ_JUPITEL",35; bonus2 bSkillAtk,"WZ_STORMGUST",35; bonus2 bSkillAtk,"WZ_VERMILION",35; bonus2 bSubRace,RC_DemiHuman,10; bonus2 bSubRace,RC_Player,10; bonus2 bAddEffWhenHit,Eff_Stone,500; bonus bMaxHPrate,20; bonus2 bIgnoreMdefClassRate,Class_Normal,20; bonus3 bAutoSpellWhenHit,"PF_FOGWALL",5,100;} else if( Class==Job_Professor ){ bonus bInt,20; bonus bDex,20; bonus bVit,20; bonus bMaxHPrate,20; bonus2 bSkillAtk,"MG_COLDBOLT",35; bonus2 bSkillAtk,"MG_FIREBOLT",20; bonus2 bSkillAtk,"MG_LIGHTNINGBOLT",20; bonus2 bSkillAtk,"WZ_EARTHSPIKE",20; bonus2 bSkillAtk,"WZ_HEAVENDRIVE",20; bonus2 bSubRace,RC_DemiHuman,10; bonus2 bSubRace,RC_Player,10; bonus bDefRate,-20; bonus bDef2Rate,-20; bonus2 bSubEle,Ele_Wind,25;} else if(Class==Job_Acolyte) { bonus bInt,20; bonus bDex,20; bonus bVit,20; bonus bMaxHPrate,20; bonus2 bSkillAtk,"AL_HOLYLIGHT",300; bonus2 bSubRace,RC_DemiHuman,10; bonus2 bSubRace,RC_Player,10; bonus2 bIgnoreMdefClassRate,Class_Normal,20; bonus bDefRate,-67; bonus bDef2Rate,-67; bonus2 bAddEffWhenHit,Eff_Silence,500; skill "SA_DISPELL",5;} },{},{}
    

    try this

  3. You have to use this version

    *setnpcdisplay("<npc name>", "<display name>", <class id>)
    

    The NPC name is the name that's in the script header, display name is the name that's shown, and the class id is the sprite id you're disguising the npc.

    setnpcdisplay(strnpcinfo(0), "Drops", .disguise);
    
    setnpcdisplay(strnpcinfo(0), "Poring", .original);
    
  4. It really depends on how optimized you want it to be.

    Let's say the size is N long.

     

    The problem with looping through the list, is that EVERY time ANY monster dies, it'll look through the list, checking N times.

    This means that the script takes O(N) time.

    If N = 1, then it's not too big of a problem. But if N = 100, then it starts becoming a huge problem.

     

    You can reduce it to O(1), by using a map (or a dictionary, you can call it what you like). Unfortunately, the Athena scripting language don't have these structures. Instead, we must use arrays.

    This idea works by putting the cash/zeny rewards in a huge array, then accessing the array using the mob id.

    If there isn't a reward, then it's zero. If there is a reward, it's non-zero(the actual reward).

     

    The OnNPCKillEvent would look like this:

    OnNPCKillEvent:
    	Zeny += .zeny_list[killedrid];
    	#CASHPOINTS += .cash_list[killedrid];
    	end;
    

    When you initialize the NPC, however, you need to fill those lists. We can use a similar system as Stolao's, but here's mine.

    //mobid, zeny, cash
    setarray .rewards[0], 
    1002, 10000, 100,
    1003, 20000, 230;
    

    I don't like strings, integers are easier.

    We then need to add the rewards into the arrays.

    for ([email protected] = 0, [email protected] < getarraysize(.rewards); [email protected] += 3) {
    	.zeny_list[.rewards[[email protected]]] = .rewards[[email protected] + 1];
    	.cash_list[.rewards[[email protected]]] = .rewards[[email protected] + 2];
    }
    

    This way, initialization takes O(N) time.

    The tradeoff, however, is memory. You now have two arrays of the size of the highest monster id you've given a reward to.

    We can make a few optimizations and we end up with this:

    -	script	#extra_drop	-1,{
    OnNPCKillEvent:
    	Zeny += .zeny_list[killedrid - .minId];
    	#CASHPOINTS += .cash_list[killedrid - .minId];
    	end;
    
    OnInit:
    	//mobid, zeny, cash
    	.minId = 1001;
    	setarray .rewards[0], 
    	1002, 10000, 100,
    	1003, 20000, 230;
    	[email protected] = getarraysize(.rewards);
    	for ([email protected] = 0, [email protected] < [email protected]; [email protected] += 3) {
    		.zeny_list[.rewards[[email protected]] - .minId] = .rewards[[email protected] + 1];
    		.cash_list[.rewards[[email protected]] - .minId] = .rewards[[email protected] + 2];
    	}
    	deletearray .rewards[0], [email protected];
    	end;
    }
    

    If you want to add items with drop rates and things, I'd recommend doing it in source (which is what I did for my project).

    I haven't tested this, but it should work. I got halfway through this script then decided to switch to source.

  5. If we put it all together:

    prontera,150,181,4 script Healer#h1-1::Healer 533,{
    	emotion 21;
    
    	while( [email protected] < .sc_size ){
    		sc_end .sc_status[[email protected]];
    		set [email protected],[email protected] + 1;
    	}
    
    	sc_start SC_BLESSING,.buff_duration,10;
    	sc_start SC_INCREASEAGI,.buff_duration,10;
    	sc_start SC_GLORIA,.buff_duration,5;
    	sc_start SC_ASPDPOTION2,.buff_duration,0;
    	sc_start SC_MAGNIFICAT,.buff_duration,10;
    	sc_start SC_SUFFRAGIUM,.buff_duration,10;
    	sc_start SC_ASSUMPTIO,.buff_duration,10;
    	percentheal 100,100;
    	if(getgroupid() >= 5 ){
    		sc_start(SC_CP_HELM, (.buff_duration), 1);
    		sc_start(SC_CP_ARMOR, (.buff_duration), 1);
    		sc_start(SC_CP_SHIELD, (.buff_duration), 1);
    		sc_start(SC_CP_WEAPON, (.buff_duration), 1);
    		switch ( basejob ) {
    			case Job_Alchemist:	set [email protected], 445; break;
    			case Job_Monk:	 set [email protected], 447; break;
    			case Job_Star_Gladiator:  set [email protected], 448; break;
    			case Job_Sage:	 set [email protected], 449; break;
    			case Job_Crusader:	set [email protected], 450; break;
    			case Job_SuperNovice:   set [email protected], 451; break;
    			case Job_Knight:	set [email protected], 452; break;
    			case Job_Wizard:	set [email protected], 453; break;
    			case Job_Priest:	set [email protected], 454; break;
    			case Job_Bard: case Job_Dancer: set [email protected], 455; break;
    			case Job_Rogue:	 set [email protected], 456; break;
    			case Job_Assassin:	set [email protected], 457; break;
    			case Job_Blacksmith:   set [email protected], 458; break;
    			case Job_Hunter:	set [email protected], 460; break;
    			case Job_Soul_Linker:   set [email protected], 461; break;
    			default:
    				if ( upper == 1 && baselevel < 70 )
    					set [email protected], 494;
    		}
    		if ( [email protected] ) {
    			sc_start4 sc_spirit, .buff_duration, 5, [email protected],0,0;
    			skilleffect [email protected], 5;
    		}
    	}
    
    	dispbottom "Thanks.";
    
    	while( getbrokenid(1) )
    		// repair getbrokenid(1);
    		repairall;
    	        // atcommand "@repairall";
    	end;
    
    
    OnInit:
    	set .buff_duration,600000;
    
    	setarray .sc_status,
    	SC_STONE,SC_FREEZE,SC_STUN,SC_SLEEP,SC_POISON,SC_CURSE,SC_SILENCE,SC_CONFUSION,SC_BLIND,SC_BLEEDING,
    	SC_QUAGMIRE,SC_AETERNA,SC_HALLUCINATION,SC_SLOWDOWN,SC_BERSERK,SC_CHANGEUNDEAD,
    	SC_STRIPWEAPON,SC_STRIPSHIELD,SC_STRIPARMOR,SC_STRIPHELM;
    	set .sc_size,getarraysize( .sc_status );
    
    
    	waitingroom " H e a l e r",0;
    	end;
    }
    
    
    
    
    
  6. It works, but it doesn't work well.

     

    Basically every time a player walks somewhere, it checks to see if there's anyone already on the cell. This will block freewalk.

     

    Unfortunately, the way the client handles skills doesn't lend itself to this system. Normally if you cast a spell out of range, the client calculates the distance it needs to travel and sends a walk request to the server. If there's someone standing on the cell that the client chose, the server will reject the request and the player will not move at all.

     

    So while it does block freewalk, it also prevents legitimate ways to occupy the same cell.

  7. If you want to change the matk ratio, you'll have to make a new case in the switch-case statement in battle_calc_magic_attack.

    For example

    case WZ_JUPITEL:
       skillratio -= 20;
       break;
    
    If you want to change the number of hits, edit db/skill_db.txt.
×
×
  • Create New...

Important Information

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