diff --git a/EQ2/source/WorldServer/LuaFunctions.cpp b/EQ2/source/WorldServer/LuaFunctions.cpp
index 6e2df544f..348941962 100644
--- a/EQ2/source/WorldServer/LuaFunctions.cpp
+++ b/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)
diff --git a/EQ2/source/WorldServer/LuaFunctions.h b/EQ2/source/WorldServer/LuaFunctions.h
index f59b26e4f..dc7cce2ac 100644
--- a/EQ2/source/WorldServer/LuaFunctions.h
+++ b/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);
diff --git a/EQ2/source/WorldServer/LuaInterface.cpp b/EQ2/source/WorldServer/LuaInterface.cpp
index e044460d7..c06adcba8 100644
--- a/EQ2/source/WorldServer/LuaInterface.cpp
+++ b/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);
diff --git a/EQ2/source/WorldServer/Player.cpp b/EQ2/source/WorldServer/Player.cpp
index 4ff395213..c0e616f69 100644
--- a/EQ2/source/WorldServer/Player.cpp
+++ b/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);
diff --git a/EQ2/source/WorldServer/Quests.cpp b/EQ2/source/WorldServer/Quests.cpp
index 9eca26f9a..dc17eb574 100644
--- a/EQ2/source/WorldServer/Quests.cpp
+++ b/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)
diff --git a/EQ2/source/WorldServer/Quests.h b/EQ2/source/WorldServer/Quests.h
index 628b54a15..06c626b25 100644
--- a/EQ2/source/WorldServer/Quests.h
+++ b/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);