Hey community,

right know I try to spawn npcs with questmarkers over their head like in WoW.
I already made the graphics and imported them. Made an item Questmarker.
Im using Mondain quest system
how to spawn a MondainQuester with this Questmarker Item at his feet? The Item is automatically over his head cause I set z+20 in the graphics
Then for example I got a quest, how to make this item visible if the npc can offer a quest and visible false after the quest is done and you cant repeat
In the Quest script? Here?

public override bool CanOffer()
{
return true;
//Questmarker set visible=true;
}

// else
// Questmarker set visible=false;

hope some understands me and can help me
Excuse me for my poor english:(
 
I guess you could take a look at how effects are done instead of using an item.
ex: effectcontroller, which can ex: place a moongate over yourself.
for this case i would suggest a timer that sends that effect.

you can take a look at how sandvortex.cs does the timer job, but instead of starting it onreceivemeleeattack() you place it in the public NPCName(Serial serial){<here>} or in the deserialize method.

when the timer ticks (checking if quest is available), make the effect on the npc.

don't hesitate to post codes if you come up with some.
 
public override bool CanOffer()
{
return true;
Questmarker questmarker = new Questmarker();
questmarker.MoveToWorld( Beo.Location, Beo.Map ); //Beo is the guy who gives the quest
}

I need to do it this way
 
You absolutely need it to be an interractive item?
if so, override the OnMove method to include the item relocalisation.

1) be sure the item is not movable. (in the marker script itself)

2) be sure to link the item with the npc with a private field, ex: private QuestMarker m_marker;
then in the
Code:
public NPCName(Serial serial)
{
}
add: m_marker = new Questmarker();
also add the same line at the end of the npc constructor.

3) add the onmove
Code:
public override bool OnMove(Direction d)
{
	return base.OnMove( d );
	if (m_marker != null)
		m_marker.MoveToWorld( Location, Map );
}

4) if you want the canoffer thing to work on props, then look at some scripts and do m_marker.Visible = true/false;

5) in the npc script be sure to add something like:
Code:
public override void OnDelete()
{
	Delete(m_marker);	//not sure about the name of the delete function, easy find.
	base.OnDelete();
}
To delete the item, then the npc, to avoid complications.
 
The best way to display properties to some users but not to others is to override the DisplayPropertiesTo(Mobile from) method. Try:

Code:
public override void DisplayPropertiesTo(Mobile from)
{
	if (this.CanTalkTo(from))
	{
		...add the property here...
	}
}
 
Thank you so much guys, but my script skills are very small! Lokai I even have no clue where to try this, in the questmarker script itself or elsewhere? then i have to determine the quests right? Let me show you my scripts so far

Here is what I have so far:
This is the Quester, the Mobile who has the Quest
using System;
using System.Collections.Generic;
using Server;
using Server.Items;

namespace Server.Engines.Quests
{
public class Beo : MondainQuester
{

public override Type[] Quests{ get{ return new Type[]
{
typeof( HeldenbrauchtdasLand )
}; } }

[Constructable]
public Beo() : base( "[Jarl von Utgard]" )
{
Name = "Beowulf";
Title = "[Jarl von Utgard]";
CantWalk = true;

}

public Beo( Serial serial ) : base( serial )
{

}

public override void InitBody()
{
InitStats( 100, 100, 25 );

Female = false;
Race = Race.Human;

Hue = 0x83EA;
HairItemID = 0x203B;
HairHue = 0x2C2;

}
// This code works but it produces questmarkers without an end!!!
//public override void OnMovement( Mobile m, Point3D oldLocation )
//{
// Questmarker questmarker = new Questmarker();
// questmarker.MoveToWorld( this.Location, this.Map );
//}

public override void InitOutfit()
{
AddItem( new ThighBoots() );
AddItem( new ElvenPants( 0x57A ) );
AddItem( new ElvenShirt( 0x711 ) );
AddItem( new Cloak( 0x21 ) );
AddItem( new Circlet() );
}


public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );

writer.Write( (int) 0 ); // version
}

public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );

int version = reader.ReadInt();
}
}
}

This is the questmarker.cs
using System;

namespace Server.Items
{
public class Questmarker : Item
{
[Constructable]
public Questmarker() : base( 0x3ffd )
{
Weight = 0;
Movable = false;
}

public Questmarker( Serial serial ) : base( serial )
{

}

public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );

writer.Write( (int)0 );
}

public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );

int version = reader.ReadInt();
}
}
}

this is the questchain.jarl
using System;
using Server;
using Server.Items;
using Server.Mobiles;

namespace Server.Engines.Quests
{
public class HeldenbrauchtdasLand : BaseQuest
{
public override QuestChain ChainID{ get{ return QuestChain.Jarl; } }
public override Type NextQuest{ get{ return typeof( ProblemeüberProbleme ); } }
//Player can only do quest once
public override bool DoneOnce{ get{ return true; } }

//This is the Quest Title the player sees at the top of the Gump
public override object Title{ get{ return "Helden braucht das Land"; } }
//This tells the story of the quest
public override object Description { get { return "Guten Tag Bürger! Ich bin Beowulf, Jarl von Utgard! Was ist Euer anliegen, Bürger? Moment mal, wo ich Euch gerade vor mir sehe. Ihr seht fähig aus und könntet mir und unserer geliebten Heimat vielleicht einen Gefallen tun. Auf den Weg zur Mine, am Pfad zwischen den beiden Bergen tummeln sich neuerdings zwei Wegelagerer. Sie bedrohen und rauben die Karawanen mit den Erzlieferungen für die Stadt. Das muss ein Ende finden. Die Stadt benötigt das Erz, damit unsere Schmiede unsere Soldaten mit Rüstung und Waffe versorgen können. Der Schutz unserer Mauern und des umliegenden Landes hat höchste Priorität! Was sagt Ihr? Nehmt Ihr euch der Sache an?"; } }
//This decides how the npc reacts in text the player refusing the quest
public override object Refuse{ get{ return "Hmm, ich habe Euch anders eingeschätzt. Nun gut, es wird sich jemand finden, der sich um das Problem kümmert!"; } }
//This is what the npc says when the player returns without completing the objective(s)
public override object Uncomplete{ get{ return "Die Wegelagerer sind noch am Leben! Geht und vollbringt die Tat!"; } }
//This is what the Quest Giver says when the player completes the quest
public override object Complete{ get{ return "Wunderbar! Ihr entlastet mich dadurch sehr! Ein Problem weniger, womit ich mich befassen muss. Hier ist eine Kleinigkeit als Geste der Dankbarkeit!"; } }

public HeldenbrauchtdasLand() : base()
{
//Slay Objective #1
AddObjective(new SlayObjective(typeof(Wegelagerer),"Wegelagerer",2 ));
}

public override void GiveRewards()
{

BankCheck gold = new BankCheck( Utility.RandomMinMax( 600, 600 ) );
if( !Owner.AddToBackpack( gold ) )
{
gold.MoveToWorld(Owner.Location,Owner.Map);
}

base.GiveRewards();
}

public override bool CanOffer()
{
return true;
}

}

public class ProblemeüberProbleme : BaseQuest
{
public override QuestChain ChainID{ get{ return QuestChain.Jarl; } }
//Player can only do quest once
public override bool DoneOnce{ get{ return true; } }

//This is the Quest Title the player sees at the top of the Gump
public override object Title{ get{ return "Probleme über Probleme"; } }
//This tells the story of the quest
public override object Description { get { return "Ihr habt Euch das letzte Mal gut geschlagen, deshalb bitte ich Euch, um eine weitere Gefälligkeit. Es herrschen Gerüchte über einen Orkspäher in der Nähe unserer Stadtmauern! Könntet Ihr zum südlichen Eingang gehen und dort in dem umliegenden Wald Nachforschungen anstellen? Falls sich dort wirklich ein Orkspäher tummelt, müsst Ihr ihn töten. Er darf keine Nachricht an das Orklager über unsere Lage überbringen, sonst wissen diese Wesen über unsere momentanen Engpässe in der Versorgung unserer Wachen Bescheid. Dies könnte dazu führen, dass Sie unsere Stadt angreifen! Und das Bürger können wir auf keinen Fall zulassen! Was sagt Ihr?"; } }
//This decides how the npc reacts in text the player refusing the quest
public override object Refuse{ get{ return "Euch scheint die Wichtigkeit dieser Aufgabe nicht bewusst. Kommt wieder wenn Ihr es Euch anders überlegt habt!"; } }
//This is what the npc says when the player returns without completing the objective(s)
public override object Uncomplete{ get{ return "Die Gerüchte über den Späher legen sich nicht. Er scheint noch am Leben zu sein! Findet ihn und tötet ihn!"; } }
//This is what the Quest Giver says when the player completes the quest.
public override object Complete{ get{ return "Ihr macht Euch gut, Bürger! Ihr scheint wirklich zu etwas zu gebrauchen zu sein! Hier ist Eure Entlohnung! 1000 Goldstücke!"; } }

public ProblemeüberProbleme() : base()
{
//Slay Objective #1
AddObjective(new SlayObjective(typeof(OrcScout),"Orkspäher",1 ));
}

public override void GiveRewards()
{
//Random gold amount to add
BankCheck gold = new BankCheck( Utility.RandomMinMax( 1000, 1000 ) );
if( !Owner.AddToBackpack( gold ) )
{
gold.MoveToWorld(Owner.Location,Owner.Map);
}

base.GiveRewards();
}

public override bool CanOffer()
{
return true;
}
}
}

I really dont know where to start :(
 
Code:
private Questmarker m_marker;
[Constructable]
public Beo() : base( "[Jarl von Utgard]" )
{
	Name = "Beowulf";
	Title = "[Jarl von Utgard]";
	CantWalk = true;
	m_marker = new Questmarker();
}
Code:
public Beo( Serial serial ) : base( serial )
{
	m_marker = new Questmarker();
}
Code:
public override void OnMove( Direction d )
{
	base.OnMove(d);
	if (m_marker != null)
		m_marker.MoveToWorld( this.Location, this.Map );
	else
		m_marker = new Questmarker(); //just in case'
}

then for the quest stuff, i've got no idea, never done quests and the npc don't seem linked to it in any way. (i'm probably blind too)
And it's not in english, so not too sure how to place stuffs.
 
I got to errors in the console, they are german, let me try to translate
1. void must be bool
2.Server.Engines.Quests.Beo_OnMove<Server.Direction>: The access modificators can not be changed at override of protected overtaken members Server.Mobile.OnMove<Server.Direction> something like that :/

Maybe you will kill me but it doesnt really matter if I'm usin runuo 2.2 :S
 
public override void OnMove( Direction d )
to
public override bool OnMove( Direction d )

lol no worry, i use runuo 2.0 rc2
 
CS0507: Line 45: Server.Engines.Quests.Beo_OnMove(Server.Direct
riffsmodifizierer können beim Überschreiben von protected des übern
rs Server.Mobile.OnMove(Server.Direction) nicht geändert werden.
 
public class Beo : MondainQuester

i guess MondainQuester could be the problem.
could you post this script please?
 
of course

+ Custom/Quests/Quests/Quester/Beo.cs:
CS0507: Line 45: Server.Engines.Quests.Beo_OnMove(Server.Direct
riffsmodifizierer können beim Überschreiben von protected des übern
rs Server.Mobile.OnMove(Server.Direction) nicht geändert werden.

I really appreciate your help
 
Code:
public override void OnMovement( Mobile m, Point3D oldLocation )
{
	base.OnMovement(m, oldLocation);

	if (m_marker != null)
		m_marker.MoveToWorld( this.Location, this.Map );
	else
		m_marker = new Questmarker(); //just in case'
}

try that instead of the move code i suggested.
 
works! approved and tested, is there a command if mobile is deleted also is the questmark?

now i need to figure out how to link the questmark to the quests
 
If you have a link "quest -> npc", then do "quest -> npc -> quest marker".
which means you can simply do a check in the onmovement, ex:

Code:
//TODO: make this a private and create a get/set method.
public bool questAvailable = false;


public override void OnMovement( Mobile m, Point3D oldLocation )
{
	base.OnMovement(m, oldLocation);
	if (m_marker != null)
	{
		m_marker.MoveToWorld( this.Location, this.Map );

		if (questAvailable)
			m_marker.Visible = false;
		else
			m_marker.Visible = true;
	}
	else
		m_marker = new Questmarker(); //just in case'
}
in the quest, you can then just do: npcvariable.questavailable = true/false
 
ok it seems my coding "skills":rolleyes: lack here
this is what i added to the questchain
no idea here

public virtual bool QuestAvialable
{
get{ return true; }
set{ CanOffer }
}

public bool questAvailable
{
if (CanOffer = true)
QuestAvailable = true;
else
QuestAvailable = false;
}
 
there is another problem
after save, restart, the questgiver are despawned and the questmarker stays in the world:mad:
 
public override void Serialize( GenericWriter writer )
public override void Deserialize( GenericReader reader )

those methods are present, so i don't really know why they despawn...
what kind of spawner are you using?

Also, the quests systems are not really my cup of tea, so i'll probably need some help too for explanations xD
 
good evening po0ka, i'm using premium spawner
no problem so far i decided that i'm satisfied if i dont have to add questmarkers manually
but the questmarker need to despawn too and the questgiver himself shouldnt despawn after restart :/
 
After restart? Perfect!
You could make it so they simply do not serialise, i would assume.
OR if this gives out bad results: add a Delete(); in the deserialise or in the public classthing(Serial serial) base: (this) thing...
 
dont know what you really mean :S but coundnt i put delete(m_marker); in deserialise function? to prevent the questmarker stays in the world?
 
No idea, never uses quests & premium spawners, so i don't know.
Maybe someone else can explain that tho.
 
i'd be interested in take a look at this when i can but had a thought, what would stop the marker for appearing for Player a but preventing Player b from seeing it?
or is that not what you're trying to do?
 
on the first page lokai mentioned a nice way to do it, problem is i cant combine this all due the lack of knowledge in scripting, right now i even have a problem with the unwanted despawn of the questgivers and the marker stays in world, btw m_marker.Delete(); in deserialize doesnt work
 
oh, sorry, put it into the move method for the quest npc, right after the base.onmove and before anything else in there
 
if that doesn't work, can you post the current npc and item script you have here? i'll try it out later and try to get it working
 
nope doesnt work tho it compiles again

using System;
using System.Collections.Generic;
using Server;
using Server.Items;

namespace Server.Engines.Quests
{
public class Beo : MondainQuester
{

//public bool questAvailable = false;

public override Type[] Quests{ get{ return new Type[]
{
typeof( HeldenbrauchtdasLand )
}; } }

private Questmarker m_marker;

[Constructable]
public Beo() : base( "[Jarl von Utgard]" )
{
Name = "Beowulf";
Title = "[Jarl von Utgard]";
m_marker = new Questmarker();

}

public Beo( Serial serial ) : base( serial )
{
m_marker = new Questmarker();
}

public override void InitBody()
{
InitStats( 100, 100, 25 );

Female = false;
Race = Race.Human;

Hue = 0x83EA;
HairItemID = 0x203B;
HairHue = 0x2C2;

}

public override void OnMovement( Mobile m, Point3D oldLocation )
{
base.OnMovement(m, oldLocation);

if (this == null) //this is the quest mobile
{
m_marker.Delete();
}
if (m_marker != null)
m_marker.MoveToWorld( this.Location, this.Map );
else
m_marker = new Questmarker(); //just in case'
}


public override void InitOutfit()
{
AddItem( new ThighBoots() );
AddItem( new ElvenPants( 0x57A ) );
AddItem( new ElvenShirt( 0x711 ) );
AddItem( new Cloak( 0x21 ) );
AddItem( new Circlet() );
}


public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );

writer.Write( (int) 0 ); // version
}

public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );

int version = reader.ReadInt();
}
}
}
 
oh and the item
using System;

namespace Server.Items
{
public class Questmarker : Item
{
[Constructable]
public Questmarker() : base( 0x3ffd )
{
Weight = 0;
Movable = false;
}

public Questmarker( Serial serial ) : base( serial )
{

}

public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );

writer.Write( (int)0 );
}

public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );

int version = reader.ReadInt();
}
}
}

and thank you mate
 
These worked for me. I used Po0ka's edits, and added something to the questmarker that might make it invisible to people who can't do the quest. Try it and let us know.
 

Attachments

  • Beowulf.cs
    2 KB · Views: 12
  • QuestMarker.cs
    1.1 KB · Views: 13
Also about the delete i was talking about adding only "Delete();" in the Deserialize of the questmarker class, not the npc'


edit**: lokai, mistake here! :p

Code:
 if (this == null) //this is the quest mobile
  {
  m_marker.Delete();  //here, delete marker, but if it's nonexistant it will send out a null reference :P
  }
  if (m_marker != null)  //here check if marker !null
  m_marker.MoveToWorld(this.Location, this.Map);
  else
  m_marker = new Questmarker(); //just in case
 
Last edited:
so first off thank you for your help
i tested this script, it compiles
but after deleting or respawning the questgiver, questmarker still stays in world
also it doenst work, my gm char made the quests and couldnt do them anymore, but questmarker still visible even if i activated player status :/
 
That's a shame. I was looking for something like "IsVisibleTo(Mobile from)" in Item.cs but it doesn't exist. So the only alternative that I can think of is to modify PlayerMobile. Please post your PlayerMobile.cs file as an attachment (don't copy paste the text, just upload the file.) I will work on it and get back to you.
 
Back