Register for your free account! | Forgot your password?

You last visited: Today at 22:46

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[Release] Basic Pet-Quest

Discussion on [Release] Basic Pet-Quest within the Metin2 PServer Guides & Strategies forum part of the Metin2 Private Server category.

Reply
 
Old   #1

 
elite*gold: 83
Join Date: Nov 2013
Posts: 2,891
Received Thanks: 2,765
[Release] Basic Pet-Quest

Ich habe mich heute mal an eine Basic Pet-Quest gesetzt. Die Boni können in der Datenbank eingestellt werden.
Ob das ganze funktioniert weiss ich nicht, weil ich zurzeit keinen Server zum Testen zur Verfügung habe. Bei Fehlern immer gerne hier im Thread melden!



Vorraussetzungen:
game.mysql_query Funktion, welche die Datensätze im Format [dataset][columnIndex] zurückgibt
Installation:
  1. Den SQL Teil aus dem obersten Kommentarblock in die Datenbank "player" einfügen
  2. Den Questlib Teil in die Questlib einfügen
  3. Wenn ipairs noch nicht in der quest_functions steht, einfügen
  4. Vnums im Trigger (vnum.use) durch die der Siegel ersetzen (Siegel muss Type 18 sein!)
  5. Quest einfügen und in die quest_list / locale_list eintragen
  6. Pets in die vorher erstellte Tabelle (pet_info) eintragen (Achtung: Es werden Fremdschlüssel benutzt. Heisst: Es können nur Siegel hinzugefügt werden, welche in der item_proto vorhanden sind und nur Monster eingetragen werden, welche in der mob_proto existieren!)
  7. Boni der Pets in die vorher erstellte Tablle (pet_affect) eintragen (Achtung: Auch hier werden Fremdschlüssel benutzt. Es können die Bonis nur eingestellt werden, wenn dieses Siegel in der pet_info Tabelle existiert!)
Zu beachten:
Die Tabelle "pet_open_affects" wird dafür genutzt, die wirklich vergegeben Boni zu speichern. Wenn also der Boni des Pets in der Tabelle "pet_affect" geändert wird, und ein Spieler während dieser Zeit sein Pet gerufen hat, werden ihm die Boni weggenommen, die er auch bekommen hat, und nicht die, die neu eingestellt wurden. Das leeren der pet_open_affects Tabelle löscht NICHT die Boni der Spieler!


Die Quest:
Code:
--[[
SQL:

CREATE TABLE pet_info (
	itemVnum int(11) NOT NULL,
	mobVnum int(11) NOT NULL,
	PRIMARY KEY(itemVnum),
	FOREIGN KEY(itemVnum) REFERENCES item_proto(vnum),
	FOREIGN KEY(mobVnum) REFERENCES mob_proto(vnum)
);

CREATE TABLE pet_affect (
	itemVnum int(11) NOT NULL,
	affectID int(11) NOT NULL,
	affectValue int(11) NOT NULL,
	PRIMARY KEY(itemVnum, affectID),
	FOREIGN KEY(itemVnum) REFERENCES pet_info(itemVnum)
);

CREATE TABLE pet_names (
	pid int(11) NOT NULL,
	itemVnum int(11) NOT NULL,
	name varchar(12) NOT NULL,
	PRIMARY KEY(pid, itemVnum),
	FOREIGN KEY(itemVnum) REFERENCES pet_info(itemVnum)
);

CREATE TABLE pet_summoned (
	pid int(11) NOT NULL,
	itemVnum int(11) NOT NULL,
	mobVnum int(11) NOT NULL,
	PRIMARY KEY(pid, itemVnum)
);

CREATE TABLE pet_open_affects (
	pid int(11) NOT NULL,
	itemVnum int(11) NOT NULL,
	affectID int(11) NOT NULL,
	affectValue int(11) NOT NULL,
	PRIMARY KEY(pid, itemVnum, affectID)
);


Questlib:

petMessage = {
	SUMMON = {
		SUCCESS = "Dein Haustier wurde zurückgeschickt.",
		ERROR_NO_INFO = "SUMMON.ERROR_NO_INFO (Keine Info zum Siegel) - Bitte einem Teamler melden"
	},
	UNSUMMON = {
		SUCCESS = "Dein Haustier wurde gerufen.",
		ERROR_NO_INFO = "UNSUMMON.ERROR_NO_INFO (Keine Info zum Siegel) - Bitte einem Teamler melden"
	}
}
]]

quest petSystem begin
	state start begin
		--Jedes Siegel 1x spawnbar
		when 123.use begin
			syschat(petSystem.summon(item.get_vnum()))
		end
		
		when login begin
			--Looptimer to check if all summoned pets are still in the players inventory
			loop_timer("check_pets", 5)
			
			for _,itemVnum in ipairs(petSystem.getSummoned()) do
				--Message is not going to be printed when logging in
				petSystem.summon(itemVnum, true)
			end
		end
		
		when check_pets.timer begin
			for _,itemVnum in ipairs(petSystem.getSummoned()) do
				if pc.count_item(itemVnum) < 1 then
					syschat("Das Siegel eines von dir gerufenen Haustieres wurde nicht mehr in deinem Inventar gefunden.")
					syschat(petSystem.unsummon(itemVnum))
				end
			end
		end
		
		--[[
			summon(itemVnum)
			Summons the pet by the given itemVnum
			
			Parameters:
			itemVnum		The item used to summon the pet
			force			If summon should be forced (default = false)
			
			Returns:		petMessage.SUMMON or (if unsummon was called) petMessage.UNSUMMON
		]]
		function summon(itemVnum, force)
			local force = force or false
			
			if petSystem.isSummoned(itemVnum) then
				local msg = petSystem.unsummon(itemVnum)
				if not force then
					return msg
				end
			end
			
			local currentInfo = petSystem.getCurrentInfo(itemVnum)
			if not currentInfo then return petMessage.SUMMON.ERROR_NO_INFO end
			
			local pid = pc.get_player_id()
			
			for _,affectPair in ipairs(currentInfo.affectData) do
				affect.add_collect(affectPair[1], affectPair[2], 60*60*24*365*10)
				game.mysql_query("INSERT INTO player.pet_open_affects (pid, itemVnum, affectID, affectValue) VALUES ("..pid..", "..itemVnum..", "..affectPair[1]..", "..affectPair[2]..");")
			end
			
			local petName = petSystem.getPetName(itemVnum) or mob_name(currentInfo.mobVnum)
			
			pet.summon(currentInfo.mobVnum, (" - "..petName), false)
			game.mysql_query("INSERT INTO player.pet_summoned (pid, itemVnum, mobVnum) VALUES ("..pid..", "..itemVnum..", "..currentInfo.mobVnum..");")
			
			return petMessage.SUMMON.SUCCESS
		end
		
		--[[
			unsummon(itemVnum)
			Unsummons the pet by the given itemVnum
			
			Parameters:
			itemVnum		The item used to summon the pet
			
			Returns:		petMessage.UNSUMMON
		]]
		function unsummon(itemVnum)
			local summonedInfo = petSystem.getSummonedInfo(itemVnum)
			if not summonedInfo then return petMessage.UNSUMMON.ERROR_NO_INFO end
			
			local pid = pc.get_player_id()
			
			for _,affectPair in ipairs(summonedInfo.affectData) do
				affect.remove_collect(affectPair[1], affectPair[2])
				game.mysql_query("DELETE FROM player.pet_open_affects WHERE pid = "..pid.." AND itemVnum = "..itemVnum.." AND affectID = "..affectPair[1].." LIMIT 1;")
			end
			
			pet.unsummon(summonedInfo.mobVnum)
			game.mysql_query("DELETE FROM player.pet_summoned WHERE pid = "..pid.." AND itemVnum = "..itemVnum.." LIMIT 1;")
			
			return petMessage.UNSUMMON.SUCCESS
		end
		
		--[[
			isSummoned(itemVnum)
			Checks if the pet with the given itemVnum is summoned
			
			Parameters:
			itemVnum		The item used to summon the pet
			
			Returns:		boolean (true, if pet is already summoned)
		]]
		function isSummoned(itemVnum)
			return in_list(itemVnum, petSystem.getSummoned())
		end
		
		--[[
			getSummoned()
			Returns all itemVnums of which a pet is summoned
			
			Paramters:
			//
			
			Returns:		table of all itemVnums currently summoned by the player
		]]
		function getSummoned()
			local pid = pc.get_player_id()
			
			local result = game.mysql_query("SELECT itemVnum FROM player.pet_summoned WHERE pid = "..pid..";") or false
			if not result or table.getn(result) < 1 then return {} end
			
			local summonedPets = {}
			for _,v in ipairs(result) do
				table.insert(summonedPets, tonumber(v[1]))
			end
			
			return summonedPets
		end
		
		--[[
			getCurrentInfo(itemVnum)
			Returns the current info for the given itemVnum from the database
			
			Parameters:
			itemVnum		The item to search info for
			
			Returns:		false (if no info found to the itemVnum) or a table with the mobVnum and all affects (affect table can be empty)
		]]
		function getCurrentInfo(itemVnum)
			local mobVnum = game.mysql_query("SELECT mobVnum FROM player.pet_info WHERE itemVnum = "..itemVnum.." LIMIT 1;") or false
			if not mobVnum or table.getn(mobVnum) < 1 then return false end
			
			local info = {mobVnum = tonumber(mobVnum[1][1]), affectData = {}}
			
			local affectData = game.mysql_query("SELECT affectID, affectValue FROM player.pet_affect WHERE itemVnum = "..itemVnum..";") or false
			if not affectData or table.getn(affectData) < 1 then return info end
			
			for _,v in ipairs(affectData) do
				table.insert(info.affectData, {tonumber(v[1]), tonumber(v[2])})
			end
			
			return info
		end
		
		--[[
			getSummonedInfo(itemVnum)
			Returns the summoned info for the given itemVnum of the player (e.g. affects have been changed but player summoned the pet before, this will return the affects the player got)
			
			Parameters:
			itemVnum		The item to search info for
			
			Returns:		false (if no info found to the itemVnum in combination with the player) or a table with the mobVnum and all affects the player got by this pet
		]]
		function getSummonedInfo(itemVnum)
			local pid = pc.get_player_id()
			
			local mobVnum = game.mysql_query("SELECT mobVnum FROM player.pet_summoned WHERE pid = "..pid.." AND itemVnum = "..itemVnum.." LIMIT 1;") or false
			if not mobVnum or table.getn(mobVnum) < 1 then return false end
			
			local info = {mobVnum = tonumber(mobVnum[1][1]), affectData = {}}
			
			local affectData = game.mysql_query("SELECT affectID, affectValue FROM player.pet_open_affects WHERE pid = "..pid.." AND itemVnum = "..itemVnum..";") or false
			if not affectData or table.getn(affectData) < 1 then return info end
			
			for _,v in ipairs(affectData) do
				table.insert(info.affectData, {tonumber(v[1]), tonumber(v[2])})
			end
			
			return info
		end
		
		--[[
			getPetName(itemVnum)
			Returns the name the player gave his pet with the given itemVnum
			
			Parameters:
			itemVnum		The item to search the name for
			
			Returns:		false (if no name set yet) or the petname
		]]
		function getPetName(itemVnum)
			local pid = pc.get_player_id()
			
			local petName = game.mysql_query("SELECT petName FROM player.pet_names WHERE pid = "..pid.." AND itemVnum "..itemVnum.." LIMIT 1;") or false
			if not petName or table.getn(petName) < 1 then return false end
			
			return petName[1][1]
		end
		
		--[[
			setPetName(itemVnum, name)
			Sets the petname for the given itemVnum
			
			Parameters:
			itemVnum		The item to set the name for
			name			The name to set
			
			Returns:
			//
		]]
		function setPetName(itemVnum, name)
			local pid = pc.get_player_id()
			
			game.mysql_query("INSERT INTO player.pet_names (pid, itemVnum, name) VALUES ("..pid..", "..itemVnum..", '"..name.."') ON DUPLICATE KEY UPDATE name = '"..name.."';")
		end
	end
end


Unterstützt durch



rollback is offline  
Thanks
15 Users
Old   #2
 
elite*gold: 0
Join Date: Sep 2013
Posts: 491
Received Thanks: 675
Quote:
Originally Posted by Seחsi View Post
Code:
		when check_pets.timer begin
			for _,itemVnum in ipairs(petSystem.getSummoned()) do
				if pc.count_item(itemVnum) < 1 then
					syschat("Das Siegel eines von dir gerufenen Haustieres wurde nicht mehr in deinem Inventar gefunden.")
					syschat(petSystem.unsummon(itemVnum))
				end
			end
		end
Den Teil brauchst du eigentlich garnicht mehr seit 34k Game(glaube ich) beim Source aufjedenfall nicht, denn sobald du das Siegel weggibst verschwindet dein Pet
.Kibito is offline  
Thanks
1 User
Old   #3


 
Kyuso /..'s Avatar
 
elite*gold: 0
Join Date: Jan 2014
Posts: 1,583
Received Thanks: 2,398
Sehr schöne Sache Felix, danke
Kyuso /.. is offline  
Thanks
1 User
Reply




All times are GMT +2. The time now is 22:47.


Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2026 elitepvpers All Rights Reserved.