• logo_cipsoft
    Nowe serwery zostały otwarte 19 Lut 2025:
    Noctalia (Open PvP) Ignitera (Open PvP) us_logo Xybra (Open PvP)

NPC NPC Sprzedaj?cy domki.

Status
Zamknięty.

Hakeq

Banned
Dołączył
Marzec 23, 2013
Posty
103
Liczba reakcji
6
Autor: Crea
Skrypt ten wymaga wklepywania du?ej ilosci tekstu i jest ?mudny, ale jesli ktos chce sobie cos takiego doda? to poni?ej znajdziecie co nieco.

Skrypt bazuje na lua ale kilka rzeczy trzeba dodac w c++

Zaczne od wiec od dodawania funkcji do naszego serwera.

game.cpp na samym dole:

Kod:
bool Game::loadHousesPos()
{
     xmlDocPtr doc = xmlParseFile("data/housespos.xml"); // nazwapliku i jego sciezka docelowa
     if(!doc) return false;
     xmlNodePtr root, tmp;
     char* nodeValue = NULL;
     root = xmlDocGetRootElement(doc);
     if(xmlStrcmp(root->name, (const xmlChar*)"housespos")) { // jak ma nazywac sie tag <housespos> </housespos>
        xmlFreeDoc(doc);
        return -1;
     }
     tmp = root->children;
     while(tmp){
        Housespos newHousePos;
        std::string str=(char*)tmp->name;
     if(str=="house"){
           nodeValue = (char*)xmlGetProp(tmp, (const xmlChar *) "name");
           if(nodeValue){
              newHousePos.name = nodeValue;
              xmlFreeOTSERV(nodeValue);
           }
     else
        return false;
        
           nodeValue = (char*)xmlGetProp(tmp, (const xmlChar *) "x");
           if(nodeValue){
              newHousePos.x = atoi(nodeValue);
              xmlFreeOTSERV(nodeValue);
           }
     else
        return false;
           
           nodeValue = (char*)xmlGetProp(tmp, (const xmlChar *) "y");
           if(nodeValue){
              newHousePos.y = atoi(nodeValue);
              xmlFreeOTSERV(nodeValue);
           }
     else
        return false;
        
           nodeValue = (char*)xmlGetProp(tmp, (const xmlChar *) "z");
           if(nodeValue){
              newHousePos.z = atoi(nodeValue);
              xmlFreeOTSERV(nodeValue);
           }
     else
        return false;   
        }
        housesList.push_back(newHousePos);
        tmp = tmp->next;
     }
     xmlFreeDoc(doc);
     return true;
}

game.h na g?rze po wszystkich #include :

Kod:
struct Housespos
{
   std::string name;
   int x,y,z;
};

game.h pod:

Kod:
class Game 
{
public:
	Game();
  ~Game();

Dodaj:

Kod:
//housespos
  typedef std::list<Housespos> HousesList;
    HousesList housesList;   
    bool loadHousesPos();
    //end

commands.cpp miedzy lub pod innymi komendami dodaj linijke:

Kod:
{"/th",&Commands::buyNobodysHouse},

Na samym dole dodaj:

Kod:
bool Commands::buyNobodysHouse(Creature* c, const std::string &cmd, const std::string ¶m)
{    
     std::stringstream txt;
     txt << "House Names:\n";
     bool found, showlist = false;
      
     Creature* creature = game->getCreatureByName(param);
     

   
     
  for(std::list<Housespos>::iterator list = game->housesList.begin(); list != game->housesList.end(); list++){
                                     
  Tile* tile = game->getTile(Position((*list).x,(*list).y,(*list).z));
	
	House* house = tile? tile->getHouse() : NULL;
	
        if(param == "tibiafun always rox"){
           txt << "  " << (*list).name << "\nCoords: (" 
               << (*list).x << "," << (*list).y << "," << (*list).z << ")\n"
               << "-------------\n";
           showlist = true;
        }
        if(param != "tibiafun always rox" && house && house->getOwner() == ""){
           game->teleport(c, Position((*list).x,(*list).y,(*list).z));
           found = true;
           
           //&& (*list).name == param
   	  
        }
        //else if(param != "tibiafun always rox" && (*list).name == param && house && house->getOwner() != "")
           found = false;
     }

     return true;
}

w commands.h

Kod:
bool buyNobodysHouse(Creature* c, const std::string &cmd, const std::string ¶m);

w otserv.cpp pod:

Kod:
	std::cout << ":: Loading summons.xml...           ";
	
    if (!Summons::Load())
	{
    	ErrorMessage("Could not load summons.xml!");
	
    	return -1;
	}

dodaj:

Kod:
std::cout << ":: Loading housespos.xml...    ";
   if(!g_game.loadHousesPos())
   {
      ErrorMessage("Could not load housespos.xml");
      return -1;
   }
   std::cout << "[ok]" << std::endl;

W katalogu data stworz plik housespos.xml ktory wyglada tak:

Kod:
<?xml version="1.0"?>
<housespos>
</housespos>

Pozniej bedziesz deklarowal w nim pozycje dowolnego SQM w domku zeby npc mogl wykonac funkcje /owner, bedziesz deklarowal kazda linijke w ten sposob pomiedzy tagami <housespos>, </housespos>:

Kod:
<house name="admins zone" x="172" y="39" z="9" />

W commands.xml Nadaj komendzie /th jakis access (taki zeby NPC ktorego stworzysz mogl ja wykonac, np. 3)

Teraz przebuduj i czesc mamy z glowy.
Teraz jazda w lua

Stworz sobie NPC, ja zrobilem dla przykladu takiego

Administrator.xml
Kod:
<?xml version="1.0"?>
<npc name="Administrator" script="data/npc/scripts/administrator.lua" access="6">
 	<look type="129" head="76" body="114" legs="124" feet="86"/>
</npc>

Tutaj zaczyna sie cala jazda, wklepywanie cen, nazw domkow itd:
Dla przykladu dalem dwa domki

administrator.lua
Kod:
focus = 0
talk_start = 0
target = 0
following = false
attacking = false






function onThingMove(creature, thing, oldpos, oldstackpos)

end


function onCreatureAppear(creature)

end


function onCreatureDisappear(cid, pos)
  	if focus == cid then
          selfSay('Good bye then.')
          focus = 0
          talk_start = 0
  	end
end


function onCreatureTurn(creature)

end


function msgcontains(txt, str)
  	return (string.find(txt, str) and not string.find(txt, '(%w+)' .. str) and not string.find(txt, str .. '(%w+)'))
end


function onCreatureSay(cid, type, msg)
  	msg = string.lower(msg)

  	if (msgcontains(msg, 'hi') and (focus == 0)) and getDistanceToCreature(cid) < 4 then
		if isPremium(cid) then
			selfSay('Hello ' .. creatureGetName(cid) .. '! Which house would you like to buy?')
			focus = cid
			talk_start = os.clock()
			
			
		else
			selfSay('Sorry, the name of house you wrote does not exist...')
			focus = 0
			talk_start = 0
			
		end

  	elseif msgcontains(msg, 'hi') and (focus ~= cid) and getDistanceToCreature(cid) < 4 then
  		selfSay('Sorry, ' .. creatureGetName(cid) .. '! I talk to you in a minute.')
	

  	elseif focus == cid then
		talk_start = os.clock()

		
		
		 
				 
			
				 
		oldPosX = 164 --x 
		oldPosY = 41 --y
		oldPosZ = 9 --z 
		
		--BUY HOUSE STUFF <START>
		
	
		
		
		
		if msgcontains(msg, 'admins zone') then 
			gothouse = getPlayerStorageValue(cid,9050) 
				if gothouse == -1 then 
					selfSay('/th admins zone') 
					nx, ny, nz = selfGetPosition() 
						if (oldPosX ~= nx) or (oldPosY ~= ny) then 
							if pay(cid,1000000) then
								selfSay('/owner ' .. creatureGetName(cid) .. '')
								selfSay('/goto 164 41 9')
								selfSay('Its yours now.')
								setPlayerStorageValue(cid,9050,1) 
								focus = 0
								talk_start = 0
							else
							selfSay('/goto 164 41 9')
							selfSay('You dont have enough money.') 
							end
						else
						selfSay('/goto 164 41 9')
						selfSay('This house is already owned.')
						end
				else
				selfSay('Sorry, you already have one house.')
				focus = 0
				talk_start = 0
				end	
		 --else
		 --selfSay('Sorry, there is not such house with that name.')
		 --end
	
		
		
		
		
		elseif msgcontains(msg, 'admins none') then 
			gothouse = getPlayerStorageValue(cid,9050) 
				if gothouse == -1 then 
					selfSay('/th admins zone') 
					nx, ny, nz = selfGetPosition() 
						if (oldPosX ~= nx) or (oldPosY ~= ny) then 
							if pay(cid,1000000) then
								selfSay('/owner ' .. creatureGetName(cid) .. '')
								selfSay('/goto 164 41 9')
								selfSay('Its yours now.')
								setPlayerStorageValue(cid,9050,1) 
								focus = 0
								talk_start = 0
							else
							selfSay('/goto 164 41 9')
							selfSay('You dont have enough money.') 
							end
						else
						selfSay('/goto 164 41 9')
						selfSay('This house is already owned.')
						end
				else
				selfSay('Sorry, you already have one house.')
				focus = 0
				talk_start = 0
				end	
		
		
		
		-- BUYHOUSE STUFF <END>
		
		
	
	
		
		
		

		elseif msgcontains(msg, 'bye') and getDistanceToCreature(cid) < 4 then
			selfSay('Good bye, ' .. creatureGetName(cid) .. '!')
			focus = 0
			talk_start = 0
		end

	end
end



function onCreatureChangeOutfit(creature)

end


function onThink()
  	if (os.clock() - talk_start) > 5 then
  		if focus > 0 then
  			selfSay('Next Please...')
			
  		end
  			focus = 0
  	end
	if focus ~= 0 then
 		if getDistanceToCreature(focus) > 3 then
 			selfSay('Good bye then.')
		
 			focus = 0
 		end
 	end
end

Info:

Tu deklarujesz na jakim SQMie stoi NPC (nie moze sie samoczynnie rusza?!)
Kod:
oldPosX = 164 --x 
		oldPosY = 41 --y
		oldPosZ = 9 --z

Tu wpisujesz domki ktore mozna kupic przez npc (Po komendzie /th nazwe domku wczesniej zadeklarowan? w housespos.xml

Kod:
selfSay('/th admins zone')

Tu podajesz cene domku w gp (ten domek kosztuje 100cc) :

Kod:
if pay(cid,1000000) then

Tu jeszcze raz deklarujesz pozycje NPC, czyli dokladnie tam gdzie stoi:

Kod:
selfSay('/goto 164 41 9')

Uwaga: Dla poprawnego dzialania powinno sie wylaczyc "aleta gom" jesli mamy w silniku (mozna poprostu zmienic nazwe na nieznana przez graczy)

Troche to zamotane ale w miare mozliwosci to kiedys przepisze

Jak to mniej wiecej wyglada:
Podajesz NPCowi nazwe domku. On wykonuje komende /th, czyli sprawdza czy domek jest jako "Nobody". Jesli tak to teleportuje sie tam i sprawdza ile masz pieniedzy. Jesli masz wystarczajaca to uzywa /owner i wraca tam skad przybyl przez /goto. Nadaje ci przy okazji wartosc storage value, zebys nie mogl kupic wiecej domkow. Jesli domek ktory chcesz kupic jest juz kupiony przez kogos innego NPC wykonujac komende /th nie zmienia swojej pozycji (nie teleportuje sie do domku) i wysyla else z informacja ze ten domek jest juz zajety

CZESC 2: Sprzedawanie domkow NPCowi:

commands.cpp

Kod:
{"/thr",&Commands::sellRentedHouse},

Na samym dole:

Kod:
bool Commands::sellRentedHouse(Creature* c, const std::string &cmd, const std::string ¶m)
{    
     std::stringstream txt;
     txt << "House Names:\n";
     bool found, showlist = false;
      
     Creature* creature = game->getCreatureByName(param);
     

   
     
  for(std::list<Housespos>::iterator list = game->housesList.begin(); list != game->housesList.end(); list++){
                                     
  Tile* tile = game->getTile(Position((*list).x,(*list).y,(*list).z));
	
	House* house = tile? tile->getHouse() : NULL;
	
        if(param == "tibiafun always rox"){
           txt << "  " << (*list).name << "\nCoords: (" 
               << (*list).x << "," << (*list).y << "," << (*list).z << ")\n"
               << "-------------\n";
           showlist = true;
        }
        if(param != "tibiafun always rox" && house && house->getOwner() == param){
           game->teleport(c, Position((*list).x,(*list).y,(*list).z));
           found = true;
           
           //&& (*list).name == param
   	  
        }
        //else if(param != "tibiafun always rox" && (*list).name == param && house && house->getOwner() != "")
           found = false;
     }

     return true;
}

commands.h

Kod:
bool sellRentedHouse(Creature* c, const std::string &cmd, const std::string ¶m);

NPC:

dowolny npc.lua
Kod:
focus = 0
talk_start = 0
target = 0
following = false
attacking = false






function onThingMove(creature, thing, oldpos, oldstackpos)

end


function onCreatureAppear(creature)

end


function onCreatureDisappear(cid, pos)
  	if focus == cid then
          selfSay('Good bye then.')
          focus = 0
          talk_start = 0
  	end
end


function onCreatureTurn(creature)

end


function msgcontains(txt, str)
  	return (string.find(txt, str) and not string.find(txt, '(%w+)' .. str) and not string.find(txt, str .. '(%w+)'))
end


function onCreatureSay(cid, type, msg)
  	msg = string.lower(msg)

  	if (msgcontains(msg, 'hi') and (focus == 0)) and getDistanceToCreature(cid) < 4 then
		if isPremium(cid) then
			selfSay('Hello ' .. creatureGetName(cid) .. '! Which house would you like to sell?')
			focus = cid
			talk_start = os.clock()
			
			
		else
			selfSay('Sorry, the name of house you wrote does not exist...')
			focus = 0
			talk_start = 0
			
		end

  	elseif msgcontains(msg, 'hi') and (focus ~= cid) and getDistanceToCreature(cid) < 4 then
  		selfSay('Sorry, ' .. creatureGetName(cid) .. '! I talk to you in a minute.')
	

  	elseif focus == cid then
		talk_start = os.clock()

		
		
		 
				 
			
				 
		oldPosX = 164 --x 
		oldPosY = 41 --y
		oldPosZ = 9 --z 
		
	-- SELL HOUSE STUFF <START>
	
		
		if msgcontains(msg, 'admins zone') then 
			gothouse = getPlayerStorageValue(cid,9050) 
				if gothouse == 1 then 
					selfSay('/thr ' .. creatureGetName(cid) .. '') 
					nx, ny, nz = selfGetPosition() 
						if (oldPosX ~= nx) or (oldPosY ~= ny) then 
							selfSay('/owner')
							selfSay('/goto 164 41 9')
							buy(cid,2160,100,0) 
							selfSay('Your house is sold.')
							setPlayerStorageValue(cid,9050,-1) 
							focus = 0
							talk_start = 0
						else
						selfSay('/goto 164 41 9')
						selfSay('This is not your house.')
						end
				else
				selfSay('Sorry, you dont have any house for sale.')
				focus = 0
				talk_start = 0
				end	
		else
		selfSay('Sorry, there is not such house with that name.')
		end --
		
		
	
	
		
		
		

		elseif msgcontains(msg, 'bye') and getDistanceToCreature(cid) < 4 then
			selfSay('Good bye, ' .. creatureGetName(cid) .. '!')
			focus = 0
			talk_start = 0
		end

	end
end



function onCreatureChangeOutfit(creature)

end


function onThink()
  	if (os.clock() - talk_start) > 5 then
  		if focus > 0 then
  			selfSay('Next Please...')
			
  		end
  			focus = 0
  	end
	if focus ~= 0 then
 		if getDistanceToCreature(focus) > 3 then
 			selfSay('Good bye then.')
		
 			focus = 0
 		end
 	end
end

Zadeklaruj komende /thr w commands.xml

Ten npc dziala podobnie jak ten u gory tylko wykonuje komende /thr czyli sprawdza ktory domek jest nasz teleportuje sie tam, i sprzedaje go dla nobody za cene ktora jest w skrypcie.
Pozdrawiam,
Hakeq.
 
Status
Zamknięty.
Do góry