Browse Source

LUA functions AddQuestStepKillByRace and AddQuestStepZoneLoc

Fix #357 - support to quest steps by race type

Eg. race 298 is gnolls
 AddQuestStepKillByRace(Quest, 1, "I need to kill five Gnolls!", 5, 100, "I need to do what is asked of me.", 1221, 298)

Fix #352 - Add AddQuestStepZoneLoc since existing AddQuestStepLocation does not support zone id and it looks for 3 sets of locations at the end of the function (so it can accept multiple arguments of locations).  AddQuestStepZoneLoc introduces 4th optional argument of zone_id for each loc set x,y,z, zone_id

AddQuestStepZoneLoc(Quest, 2, "Go to Oakmyst Falls", 10, "Visit the Oakmyst location hinted of in the line "The life giver billows and feeds."", 11, 994, 0, -204, zoneid, anotherx, anothery, anotherz, anotherzoneid)
Image 2 years ago
parent
commit
144817fdbe

+ 58 - 7
EQ2/source/WorldServer/LuaFunctions.cpp

@@ -3737,8 +3737,8 @@ int EQ2Emu_lua_AddQuestStep(lua_State* state) {
 	}
 	return 0;
 }
-
-int EQ2Emu_lua_AddQuestStepKill(lua_State* state) {
+int EQ2Emu_lua_AddQuestStepKillLogic(lua_State* state, int8 type)
+{
 	if (!lua_interface)
 		return 0;
 	Quest* quest = lua_interface->GetQuest(state);
@@ -3752,16 +3752,16 @@ int EQ2Emu_lua_AddQuestStepKill(lua_State* state) {
 		const char* taskgroup = 0;
 		if (str_taskgroup.length() > 0)
 			taskgroup = str_taskgroup.c_str();
-		int32 npc_id = 0;
+		int32 id = 0;
 		vector<int32>* ids = 0;
 		int i = 0;
-		while ((npc_id = lua_interface->GetInt32Value(state, 8 + i))) {
+		while ((id = lua_interface->GetInt32Value(state, 8 + i))) {
 			if (ids == 0)
 				ids = new vector<int32>;
-			ids->push_back(npc_id);
+			ids->push_back(id);
 			i++;
 		}
-		QuestStep* quest_step = quest->AddQuestStep(step, QUEST_STEP_TYPE_KILL, description, ids, quantity, taskgroup, 0, 0, percentage, 0);
+		QuestStep* quest_step = quest->AddQuestStep(step, type, description, ids, quantity, taskgroup, 0, 0, percentage, 0);
 		if (quest_step && icon > 0 && quantity > 0)
 			quest_step->SetIcon(icon);
 		if (quest->GetPlayer()) {
@@ -3772,6 +3772,13 @@ int EQ2Emu_lua_AddQuestStepKill(lua_State* state) {
 	}
 	return 0;
 }
+int EQ2Emu_lua_AddQuestStepKill(lua_State* state) {
+	return EQ2Emu_lua_AddQuestStepKillLogic(state, QUEST_STEP_TYPE_KILL);
+}
+
+int EQ2Emu_lua_AddQuestStepKillByRace(lua_State* state) {
+	return EQ2Emu_lua_AddQuestStepKillLogic(state, QUEST_STEP_TYPE_KILL_RACE_REQ);
+}
 
 int EQ2Emu_lua_AddQuestStepChat(lua_State* state) {
 	if (!lua_interface)
@@ -3843,6 +3850,47 @@ int EQ2Emu_lua_AddQuestStepObtainItem(lua_State* state) {
 	return 0;
 }
 
+int EQ2Emu_lua_AddQuestStepZoneLoc(lua_State* state) {
+	if (!lua_interface)
+		return 0;
+	Quest* quest = lua_interface->GetQuest(state);
+	if (quest) {
+		int32 step = lua_interface->GetInt32Value(state, 2);
+		string description = lua_interface->GetStringValue(state, 3);
+		float max_variation = lua_interface->GetFloatValue(state, 4);
+		string str_taskgroup = lua_interface->GetStringValue(state, 5);
+		int16 icon = lua_interface->GetInt16Value(state, 6);
+		const char* taskgroup = 0;
+		if (str_taskgroup.length() > 0)
+			taskgroup = str_taskgroup.c_str();
+		vector<Location>* locations = 0;
+		int8 i = 7;
+		int8 num_args = (int8)lua_interface->GetNumberOfArgs(state);
+		while (true) {
+			Location loc;
+			loc.x = lua_interface->GetFloatValue(state, i);
+			loc.y = lua_interface->GetFloatValue(state, i + 1);
+			loc.z = lua_interface->GetFloatValue(state, i + 2);
+			loc.zone_id = lua_interface->GetInt32Value(state, i + 3);
+
+			if (loc.x == 0 && loc.y == 0 && loc.z == 0)
+				break;
+			if (locations == 0)
+				locations = new vector<Location>;
+			locations->push_back(loc);
+			i += 4;
+		}
+		QuestStep* quest_step = quest->AddQuestStep(step, QUEST_STEP_TYPE_LOCATION, description, 0, 1, taskgroup, locations, max_variation);
+		if (quest_step && icon > 0)
+			quest_step->SetIcon(icon);
+		if (quest->GetPlayer()) {
+			Client* client = quest->GetPlayer()->GetZone()->GetClientBySpawn(quest->GetPlayer());
+			quest->GetPlayer()->GetZone()->SendQuestUpdates(client);
+		}
+	}
+	return 0;
+}
+
 int EQ2Emu_lua_AddQuestStepLocation(lua_State* state) {
 	if (!lua_interface)
 		return 0;
@@ -3857,12 +3905,15 @@ int EQ2Emu_lua_AddQuestStepLocation(lua_State* state) {
 		if (str_taskgroup.length() > 0)
 			taskgroup = str_taskgroup.c_str();
 		vector<Location>* locations = 0;
-		int i = 7;
+		int8 i = 7;
+		int8 num_args = (int8)lua_interface->GetNumberOfArgs(state);
 		while (true) {
 			Location loc;
 			loc.x = lua_interface->GetFloatValue(state, i);
 			loc.y = lua_interface->GetFloatValue(state, i + 1);
 			loc.z = lua_interface->GetFloatValue(state, i + 2);
+			loc.zone_id = 0;
+			
 			if (loc.x == 0 && loc.y == 0 && loc.z == 0)
 				break;
 			if (locations == 0)

+ 4 - 0
EQ2/source/WorldServer/LuaFunctions.h

@@ -265,10 +265,14 @@ int EQ2Emu_lua_SetCoinTmpReward(lua_State* state);
 int EQ2Emu_lua_SetQuestRewardComment(lua_State* state);
 int EQ2Emu_lua_SetQuestRewardExp(lua_State* state);
 int EQ2Emu_lua_AddQuestStep(lua_State* state);
+int EQ2Emu_lua_AddQuestStepKillLogic(lua_State* state);
 int EQ2Emu_lua_AddQuestStepKill(lua_State* state);
+int EQ2Emu_lua_AddQuestStepKillByRace(lua_State* state);
 int EQ2Emu_lua_AddQuestStepChat(lua_State* state);
 int EQ2Emu_lua_AddQuestStepObtainItem(lua_State* state);
+int EQ2Emu_lua_AddQuestStepZoneLoc(lua_State* state);
 int EQ2Emu_lua_AddQuestStepLocation(lua_State* state);
+int EQ2Emu_lua_AddQuestStepLoc(lua_State* state);
 int EQ2Emu_lua_AddQuestStepSpell(lua_State* state);
 int EQ2Emu_lua_AddQuestStepCraft(lua_State* state);
 int EQ2Emu_lua_AddQuestStepHarvest(lua_State* state);

+ 2 - 0
EQ2/source/WorldServer/LuaInterface.cpp

@@ -1104,9 +1104,11 @@ void LuaInterface::RegisterFunctions(lua_State* state) {
 	lua_register(state, "SetQuestRewardComment", EQ2Emu_lua_SetQuestRewardComment);
 	lua_register(state, "SetQuestRewardExp", EQ2Emu_lua_SetQuestRewardExp);
 	lua_register(state, "AddQuestStepKill", EQ2Emu_lua_AddQuestStepKill);
+	lua_register(state, "AddQuestStepKillByRace", EQ2Emu_lua_AddQuestStepKillByRace);
 	lua_register(state, "AddQuestStep", EQ2Emu_lua_AddQuestStep);
 	lua_register(state, "AddQuestStepChat", EQ2Emu_lua_AddQuestStepChat);
 	lua_register(state, "AddQuestStepObtainItem", EQ2Emu_lua_AddQuestStepObtainItem);
+	lua_register(state, "AddQuestStepZoneLoc", EQ2Emu_lua_AddQuestStepZoneLoc);
 	lua_register(state, "AddQuestStepLocation", EQ2Emu_lua_AddQuestStepLocation);
 	lua_register(state, "AddQuestStepSpell", EQ2Emu_lua_AddQuestStepSpell);
 	lua_register(state, "AddQuestStepCraft", EQ2Emu_lua_AddQuestStepCraft);

+ 1 - 1
EQ2/source/WorldServer/Player.cpp

@@ -4613,7 +4613,7 @@ vector<Quest*>* Player::CheckQuestsLocationUpdate(){
 	map<int32, Quest*>::iterator itr;
 	MPlayerQuests.lock();
 	for(itr = player_quests.begin(); itr != player_quests.end(); itr++){
-		if(itr->second && itr->second->CheckQuestLocationUpdate(GetX(), GetY(), GetZ())){
+		if(itr->second && itr->second->CheckQuestLocationUpdate(GetX(), GetY(), GetZ(), (GetZone() ? GetZone()->GetZoneID() : 0))){
 			if(!quest_updates)
 				quest_updates = new vector<Quest*>();
 			quest_updates->push_back(itr->second);

+ 46 - 21
EQ2/source/WorldServer/Quests.cpp

@@ -22,6 +22,7 @@
 #include "Player.h"
 #include "LuaInterface.h"
 #include "Spells.h"
+#include "RaceTypes/RaceTypes.h"
 #include "../common/Log.h"
 
 #ifdef WIN32
@@ -33,6 +34,7 @@
 extern LuaInterface* lua_interface;
 extern ConfigReader configReader;
 extern MasterFactionList master_faction_list;
+extern MasterRaceTypeList race_types_list;
 
 QuestStep::QuestStep(int32 in_id, int8 in_type, string in_description, vector<int32>* in_ids, int32 in_quantity, const char* in_task_group, vector<Location>* in_locations, float in_max_variation, float in_percentage, int32 in_usableitemid){
 	type = in_type;
@@ -144,6 +146,21 @@ bool QuestStep::CheckStepKillUpdate(int32 id){
 	return ret;
 }
 
+bool QuestStep::CheckStepKillRaceReqUpdate(Spawn* spawn){
+	bool ret = false;
+	if(ids){
+		for(int32 i=0;i<ids->size();i++){
+			if(ids->at(i) == spawn->GetRace() ||
+			ids->at(i) == race_types_list.GetRaceType(spawn->GetModelType()) ||
+			ids->at(i) == race_types_list.GetRaceBaseType(spawn->GetModelType())){
+				ret = true;
+				break;
+			}
+		}
+	}
+	return ret;
+}
+
 bool QuestStep::CheckStepChatUpdate(int32 id){
 	bool ret = false;
 	if(ids){
@@ -198,12 +215,15 @@ bool QuestStep::CheckStepItemUpdate(int32 id){
 	return ret;
 }
 
-bool QuestStep::CheckStepLocationUpdate(float char_x, float char_y, float char_z){
+bool QuestStep::CheckStepLocationUpdate(float char_x, float char_y, float char_z, int32 zone_id){
 	bool ret = false;
 	if (locations) {
 		for (int32 i=0; i < locations->size(); i++) {
 			float total_diff = 0;
 			Location loc = locations->at(i);
+			if(loc.zone_id > 0 && loc.zone_id != zone_id)
+				continue;
+
 			float diff = loc.x - char_x; //Check X
 			if(diff < 0)
 				diff *= -1;
@@ -523,26 +543,31 @@ bool Quest::CheckQuestKillUpdate(Spawn* spawn, bool update){
 	MQuestSteps.lock();
 	for(int32 i=0;i<quest_steps.size(); i++){
 		step = quest_steps[i];
-		if(step && step->GetStepType() == QUEST_STEP_TYPE_KILL && !step->Complete() && step->CheckStepKillUpdate(id)){
-			if (update == true) {
-				bool passed = true;
-				if (step->GetPercentage() < 100)
-					passed = (step->GetPercentage() > MakeRandomFloat(0, 100));
-				if (passed) {
-					//Call the progress action function with the total amount of progress actually granted
-					prog_added = step->AddStepProgress(1);
-					if (lua_interface && progress_actions[step->GetStepID()].length() > 0 && prog_added > 0)
-						lua_interface->CallQuestFunction(this, progress_actions[step->GetStepID()].c_str(), player, prog_added);
-					step_updates.push_back(step);
-					step->SetUpdateName(spawn->GetName());
+		if(!step)
+			continue;
+
+			if((step->GetStepType() == QUEST_STEP_TYPE_KILL && !step->Complete() && step->CheckStepKillUpdate(id)) ||
+			 (step->GetStepType() == QUEST_STEP_TYPE_KILL_RACE_REQ && !step->Complete() && step->CheckStepKillRaceReqUpdate(spawn)))
+			{
+				if (update == true) {
+					bool passed = true;
+					if (step->GetPercentage() < 100)
+						passed = (step->GetPercentage() > MakeRandomFloat(0, 100));
+					if (passed) {
+						//Call the progress action function with the total amount of progress actually granted
+						prog_added = step->AddStepProgress(1);
+						if (lua_interface && progress_actions[step->GetStepID()].length() > 0 && prog_added > 0)
+							lua_interface->CallQuestFunction(this, progress_actions[step->GetStepID()].c_str(), player, prog_added);
+						step_updates.push_back(step);
+						step->SetUpdateName(spawn->GetName());
+						ret = true;
+					}
+					else
+						step_failures.push_back(step);
+				}
+				else {
 					ret = true;
 				}
-				else
-					step_failures.push_back(step);
-			}
-			else {
-				ret = true;
-			}
 		}
 	}
 	MQuestSteps.unlock();
@@ -811,14 +836,14 @@ bool Quest::CheckQuestHarvestUpdate(int32 id, int32 quantity){
 	return ret;
 }
 
-bool Quest::CheckQuestLocationUpdate(float char_x, float char_y, float char_z){
+bool Quest::CheckQuestLocationUpdate(float char_x, float char_y, float char_z, int32 zone_id){
 	QuestStep* step = 0;
 	bool ret = false;
 	int32 prog_added = 0;
 	MQuestSteps.lock();
 	for(int32 i=0;i<quest_steps.size(); i++){
 		step = quest_steps[i];
-		if(step && step->GetStepType() == QUEST_STEP_TYPE_LOCATION && !step->Complete() && step->CheckStepLocationUpdate(char_x, char_y, char_z)){
+		if(step && step->GetStepType() == QUEST_STEP_TYPE_LOCATION && !step->Complete() && step->CheckStepLocationUpdate(char_x, char_y, char_z, zone_id)){
 			//Call the progress action function with the total amount of progress actually granted
 			prog_added = step->AddStepProgress(1);
 			if(lua_interface && progress_actions[step->GetStepID()].length() > 0 && prog_added > 0)

+ 5 - 2
EQ2/source/WorldServer/Quests.h

@@ -32,6 +32,7 @@
 #define	QUEST_STEP_TYPE_NORMAL			6
 #define QUEST_STEP_TYPE_CRAFT           7
 #define QUEST_STEP_TYPE_HARVEST         8
+#define	QUEST_STEP_TYPE_KILL_RACE_REQ	9 // kill using race type requirement instead of npc db id
 
 #define QUEST_DISPLAY_STATUS_HIDDEN			0
 #define QUEST_DISPLAY_STATUS_NO_CHECK		1
@@ -57,6 +58,7 @@ struct Location {
 	float x;
 	float y;
 	float z;
+	int32 zone_id;
 };
 
 class QuestStep{
@@ -64,10 +66,11 @@ public:
 	QuestStep(int32 in_id, int8 in_type, string in_description, vector<int32>* in_ids, int32 in_quantity, const char* in_task_group, vector<Location>* in_locations, float in_max_variation, float in_percentage, int32 in_usableitemid);
 	QuestStep(QuestStep* old_step);
 	~QuestStep();
+	bool			CheckStepKillRaceReqUpdate(Spawn* spawn);
 	bool			CheckStepKillUpdate(int32 id);
 	bool			CheckStepChatUpdate(int32 id);
 	bool			CheckStepItemUpdate(int32 id);
-	bool			CheckStepLocationUpdate(float char_x, float char_y, float char_z);
+	bool			CheckStepLocationUpdate(float char_x, float char_y, float char_z, int32 zone_id);
 	bool			CheckStepSpellUpdate(int32 id);
 	int32			AddStepProgress(int32 val);
 	void			SetStepProgress(int32 val);
@@ -160,7 +163,7 @@ public:
 	bool				CheckQuestKillUpdate(Spawn* spawn, bool update = true);
 	bool				CheckQuestChatUpdate(int32 id, bool update = true);
 	bool				CheckQuestItemUpdate(int32 id, int8 quantity = 1);
-	bool				CheckQuestLocationUpdate(float char_x, float char_y, float char_z);
+	bool				CheckQuestLocationUpdate(float char_x, float char_y, float char_z, int32 zone_id);
 	bool				CheckQuestSpellUpdate(Spell* spell);
 	bool                CheckQuestCraftUpdate(int32 id, int32 quantity = 1);
 	bool                CheckQuestHarvestUpdate(int32 id, int32 quantity = 1);