Jump to content

Stun player from quest


Recommended Posts

There are 2 ways to do this.

1) Direct quest edit

    PROS:

  • Quick, simple fix, anyone can do it
  • Bypasses immunity

    CONS:

  • Not as stable as 2nd way

2) Source edit

    PROS:

  • Stable solution
  • Your very own lua function on stunning people

    CONS:

  • Does NOT bypass immunity (people with immunity attribute on their shield won't be affected by this)
  • More advanced implementation (recommended to back-up files, more advanced knowledge needed to edit according to your specifications)
  • Not tested (by me)

    This method will require you to compile a new QC file (add the new command in game/src/quest/quest_functions and then gmake -j20 in that directory)

Direct quest edit solution

In this example I will be using the item by vnum 31001

stun_quest.lua:

Spoiler

quest stun_quest begin
    state start begin
		when 31001.use begin
			affect.add(210, 0, 2) -- Replace 2 with the duration of the affect you want to set (in seconds).
		end
    end
end

 

Source edit solution

Go to game/src and edit the following in questlua_affect.cpp:

Spoiler

Add this to the inclludes:


#include battle.h

Find this function:


int affect_remove_all_collect( lua_State* L )
{
	...
}

Add below the closing curly brace:


int affect_stun()
{
	CQuestManager & q = CQuestManager::instance();
  	LPCHARACTER ch = q.GetCurrentCharacterPtr();
  
  	ch->AddAffect(AFFECT_QUEST_START_IDX, AFFECT_STUN, 0, 0, 2, 0, false); // Edit 2 by your stun duration specification (in seconds)

  	return 0;
}

And of course find:


{ "get_apply_on",	affect_get_apply_on },

and add this below:


{ "stun",	affect_stun },

After that, you can use this in a quest like this:

stun_quest.lua


quest stun_quest begin
    state start begin
		when 31001.use begin
			affect.stun()
		end
    end
end

REMEMBER: If you use the second way, you need to add affect.stun in quest_functions, both in SF/locale/country/quest and game/src/quest and recompile the QC in game/src/quest

I hope you found this helpful. Again, the second way is not tested and could be bugged (but I don't think so)

Best regards

  • Love 1
Link to comment
Share on other sites

10 hours ago, Mind Rapist said:

There are 2 ways to do this.

1) Direct quest edit

    PROS:

  • Quick, simple fix, anyone can do it
  • Bypasses immunity

    CONS:

  • Not as stable as 2nd way

2) Source edit

    PROS:

  • Stable solution
  • Your very own lua function on stunning people

    CONS:

  • Does NOT bypass immunity (people with immunity attribute on their shield won't be affected by this)
  • More advanced implementation (recommended to back-up files, more advanced knowledge needed to edit according to your specifications)
  • Not tested (by me)

    This method will require you to compile a new QC file (add the new command in game/src/quest/quest_functions and then gmake -j20 in that directory)

Direct quest edit solution

In this example I will be using the item by vnum 31001

stun_quest.lua:

  Hide contents


quest stun_quest begin
    state start begin
		when 31001.use begin
			affect.add(210, 0, 2) -- Replace 2 with the duration of the affect you want to set (in seconds).
		end
    end
end

 

Source edit solution

Go to game/src and edit the following in questlua_affect.cpp:

  Reveal hidden contents

Add this to the inclludes:



#include battle.h

Find this function:



int affect_remove_all_collect( lua_State* L )
{
	...
}

Add below the closing curly brace:



int affect_stun()
{
	CQuestManager & q = CQuestManager::instance();
  	LPCHARACTER ch = q.GetCurrentCharacterPtr();
  
  	ch->AddAffect(AFFECT_QUEST_START_IDX, AFFECT_STUN, 0, 0, 2, 0, false); // Edit 2 by your stun duration specification (in seconds)

  	return 0;
}

And of course find:



{ "get_apply_on",	affect_get_apply_on },

and add this below:



{ "stun",	affect_stun },

After that, you can use this in a quest like this:

stun_quest.lua



quest stun_quest begin
    state start begin
		when 31001.use begin
			affect.stun()
		end
    end
end

REMEMBER: If you use the second way, you need to add affect.stun in quest_functions, both in SF/locale/country/quest and game/src/quest and recompile the QC in game/src/quest

I hope you found this helpful. Again, the second way is not tested and could be bugged (but I don't think so)

Best regards

Thank you for answering, unfortunately the quest doesn`t do anything with that affect, applying another affect works, tried even (210, 1, 2) still nothing.

I want to stun them even with anti stun bonus on their shield. Thanks!

 

Edit: if i try to do it using       

 affect.add_collect(apply.MOV_SPEED, -10000, 5)
 affect.add_collect(apply.ATT_SPEED, -10000, 5)

The player has to mount/unmount for the effect to be gone even after 5 sec.

Link to comment
Share on other sites

Have a look at questlua_affect.cpp->int aff_affect(lua_state * L)

int affect_add(lua_State * L)
{
	if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2) || !lua_isnumber(L, 3))
	{
		sys_err("invalid argument");
		return 0;
	}

	CQuestManager & q = CQuestManager::instance();

	BYTE applyOn = (BYTE) lua_tonumber(L, 1);

	LPCHARACTER ch = q.GetCurrentCharacterPtr();

	if (applyOn >= MAX_APPLY_NUM || applyOn < 1)
	{
		sys_err("apply is out of range : %d", applyOn);
		return 0;
	}

	if (ch->FindAffect(AFFECT_QUEST_START_IDX, applyOn)) // 퀘스트로 인해 같은 곳에 효과가 걸려있으면 스킵
		return 0;

	long value = (long) lua_tonumber(L, 2);
	long duration = (long) lua_tonumber(L, 3);

	ch->AddAffect(AFFECT_QUEST_START_IDX, aApplyInfo[applyOn].bPointType, value, 0, duration, 0, false);

	return 0;
}


where L1 = affect ID, L2 = affect value, L3 = duration.

If you use /stun MyChar as a GM and you refresh player.affect  in the database you will see a new affect under the dwPID of the character stunned. The bApplyOn value is the id of the affect in the system (our case 210). If you want to check your affect ids, open the file affect.h  in game/src and search for the following:

enum EAffectTypes
{
	AFFECT_NONE,

	AFFECT_MOV_SPEED		= 200,
	AFFECT_ATT_SPEED,
	AFFECT_ATT_GRADE,
	AFFECT_INVISIBILITY,
	AFFECT_STR,
	AFFECT_DEX,			// 205
	AFFECT_CON,	
	AFFECT_INT,	
	AFFECT_FISH_MIND_PILL,

	AFFECT_POISON,
	AFFECT_STUN,		// 210
	AFFECT_SLOW,
	AFFECT_DUNGEON_READY,
	AFFECT_DUNGEON_UNIQUE,
...

As you can see, the ids start from 200 and go on. The AFFECT_STUN is the 10th in the row, which gives it the ID of 210. To be sure, open your affect.h and see your ID of AFFECT_STUN.

I also saw that you changed the value (0->1). The value on this affect is not important as it can only be a true (exists on the database table) or false (not found in the database table)

I hope this helps

Link to comment
Share on other sites

3 hours ago, Mind Rapist said:

Have a look at questlua_affect.cpp->int aff_affect(lua_state * L)


int affect_add(lua_State * L)
{
	if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2) || !lua_isnumber(L, 3))
	{
		sys_err("invalid argument");
		return 0;
	}

	CQuestManager & q = CQuestManager::instance();

	BYTE applyOn = (BYTE) lua_tonumber(L, 1);

	LPCHARACTER ch = q.GetCurrentCharacterPtr();

	if (applyOn >= MAX_APPLY_NUM || applyOn < 1)
	{
		sys_err("apply is out of range : %d", applyOn);
		return 0;
	}

	if (ch->FindAffect(AFFECT_QUEST_START_IDX, applyOn)) // 퀘스트로 인해 같은 곳에 효과가 걸려있으면 스킵
		return 0;

	long value = (long) lua_tonumber(L, 2);
	long duration = (long) lua_tonumber(L, 3);

	ch->AddAffect(AFFECT_QUEST_START_IDX, aApplyInfo[applyOn].bPointType, value, 0, duration, 0, false);

	return 0;
}


where L1 = affect ID, L2 = affect value, L3 = duration.

If you use /stun MyChar as a GM and you refresh player.affect  in the database you will see a new affect under the dwPID of the character stunned. The bApplyOn value is the id of the affect in the system (our case 210). If you want to check your affect ids, open the file affect.h  in game/src and search for the following:


enum EAffectTypes
{
	AFFECT_NONE,

	AFFECT_MOV_SPEED		= 200,
	AFFECT_ATT_SPEED,
	AFFECT_ATT_GRADE,
	AFFECT_INVISIBILITY,
	AFFECT_STR,
	AFFECT_DEX,			// 205
	AFFECT_CON,	
	AFFECT_INT,	
	AFFECT_FISH_MIND_PILL,

	AFFECT_POISON,
	AFFECT_STUN,		// 210
	AFFECT_SLOW,
	AFFECT_DUNGEON_READY,
	AFFECT_DUNGEON_UNIQUE,
...

As you can see, the ids start from 200 and go on. The AFFECT_STUN is the 10th in the row, which gives it the ID of 210. To be sure, open your affect.h and see your ID of AFFECT_STUN.

I also saw that you changed the value (0->1). The value on this affect is not important as it can only be a true (exists on the database table) or false (not found in the database table)

I hope this helps

Thanks again! In my case it`s also 210, but let`s say i try to put mov speed like : affect.add_collect(apply.MOV_SPEED, 15, 60) it will work, but if i use it`s id ( 200 ) affect.add_collect(200, 15, 60) it will not work. Also in database if i stun with the command will show bType = 210. Maybe there`s something wrong on my side of server, and i`ll deal with it using movement speed and attack speed, thanks a lot for your time helping me!

Link to comment
Share on other sites

  • 4 months later...
  • Forum Moderator
On 1/7/2019 at 12:56 AM, Hust said:

Still nothing

That's the correct way.

int affect_stun(lua_State * L)
{
	const uint32_t lDuration = 30; // seconds
  	const LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
	if (ch)
		ch->AddAffect(AFFECT_STUN, POINT_NONE, 0, AFF_STUN, lDuration, 0, true);
  	return 0;
}

 

  • Love 2
Link to comment
Share on other sites

  • Bronze
9 hours ago, VegaS™ said:

That's the correct way.


int affect_stun(lua_State * L)
{
	const uint32_t lDuration = 30; // seconds
  	const LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
	if (ch)
		ch->AddAffect(AFFECT_STUN, POINT_NONE, 0, AFF_STUN, lDuration, 0, true);
  	return 0;
}

 

Why uint32_t instead of DWORD? (Not theoretical (that's everywhere on internet), i want it in terms of usage)

As long as I'll be a threat for you , i will always be your target :3

Link to comment
Share on other sites

  • Premium
3 hours ago, Braxy said:

I think i was quite clear about what i want to know.

Anyway i want the reply from him.

You do realize that happens to correspond to unsigned int, right?

DWORD has a specific range the format Windows functions rely on, so if you require that specific range you can use that type, but that is not the case.

Also note unsigned int does not necessary have the range 0 to 4,294,967,295.  -> https://stackoverflow.com/questions/271076/what-is-the-difference-between-an-int-and-a-long-in-c/271132#271132

 

 

"Nothing's free in this life.

Ignorant people have an obligation to make up for their ignorance by paying those who help them.

Either you got the brains or cash, if you lack both you're useless."

Syreldar

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.