• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

[Sabrehaven] NPC script - String to PlayerName

X X X

Newb
Joined
Jul 26, 2015
Messages
148
Reaction score
13
I'm working with the Sabrehaven distribution, and I'm trying to recreate the behavior from the Dead Bureaucrats in the PoI quest. For the quest to be accurate, you're supposed to talk with the NPCs and they ask you for your name and vocation.

In Lua, that's super easy:

Lua:
if msgcontains(msg, player:getName()) then
        if npcHandler.topic[cid] == 1 then
            npcHandler:say("Alright |PLAYERNAME|. Vocation?", cid)
            npcHandler.topic[cid] = 2
        end
end

But Sabrehaven uses the .npc files, and after looking through behaviourdatabse.cpp, I'm at a loss as to how to accomplish this. Here is what my npc file looks like so far:

Code:
Name = "A Dead Bureaucrat"
Outfit = (33,0-0-0-0-0)
Home = [32729,32283,15]
Radius = 2

Behaviour = {
ADDRESS,"hello$",male,!   -> "Welcome to the atrium of Pumin's Domain, young man. We require some information from you before we can let you pass. Where do you want to go?"
ADDRESS,"hi$",male,!      -> *
ADDRESS,"hello$",female,! -> "Hello beautiful lady, welcome to the atrium of Pumin's Domain. We require some information from you before we can let you pass. Where do you want to go?"
ADDRESS,"hi$",female,!    -> *
ADDRESS,"hello$",QuestValue(17514)>0,! -> "You again. I told my master that you wish to end your stupid life in his domain but you need Form 356 to get there. What do you need this time?"
ADDRESS,"hi$",QuestValue(17514)>0,!    -> *
ADDRESS,!          -> Idle
BUSY,"hello$",!    -> "Please wait your turn, %N.", Queue
BUSY,"hi$",!       -> *
BUSY,!             -> NOP
VANISH,!           -> "Good bye and don't forget me!"

"bye"             -> "Good bye and don't forget me!", Idle
"farewell"        -> *
"job"           -> "I'm a bureaucrat who does not even find the time to eat. Just look how bony I am! *SIGH*"
"name"          -> "Sorry, I seem to have forgotten it!"

"pumin",QuestValue(17514)<1  -> "Sure, where else. Everyone likes to meet my master, he is a great demon, isn't he? Your name is ...?", Topic=1
"356",QuestValue(17514)=8 -> "INCREDIBLE, you did it!! Have fun at Pumin's Domain!", SetQuestValue(17514,9)

Topic=1,"<WHAT DO I PUT HERE??>"       -> "Alright %N. Vocation?", Topic=2

Topic=2,Sorcerer,"sorcerer"      -> "Huhu, please don't hurt me with your wand! Reason of your visit?", Topic=3
Topic=2,Druid,"druid"            -> "D R U I D, is that right?! What do you want from me?", Topic=3
Topic=2,Paladin,"paladin"        -> "A paladin! Great! Reason of your visit?", Topic=3
Topic=2,Knight,"knight"          -> "A noble warrior! Reason of your visit?", Topic=3

Topc=3,"pumin",QuestValue(17514)<1  -> "How very interesting. I need to tell that to my master immediately. Please go to my colleagues and ask for Form 356. You will need it in order to proceed.", SetQuestValue(17514,1)

"411",QuestValue(17514)=3  -> "Form 411? You need Form 287 to get that! Do you have it?",  Topic=4
"411",QuestValue(17514)=5  -> "Form 411? You need Form 287 to get that! Do you have it?",  Topic=5

Topc=4,"no",QuestValue(17514)=3  -> "Oh, what a pity. Go see one of my colleagues. I give you the permission to get Form 287. Bye!", SetQuestValue(17514,4)

Topc=5,"yes",QuestValue(17514)=5  -> "Great. Here you are. Form 411. Come back anytime you want to talk. Bye.", SetQuestValue(17514,6)

I know that %N is how you tell the NPC to say the player's name in their dialogue, but it does NOT work the other way around.

To put it simply: what is the .npc format way to do "if msgcontains(msg, player:getName())"?

Thanks
 
Last edited:
Solution
Some overcomplication going on here. No need for testing with "Topic=1,"X X X" or whatever. OP you're on the right track:

In behaviourdatabase.h:
C++:
BEHAVIOUR_TYPE_MESSAGE_PLAYERNAME, // return the player's name

Then in behaviourdatabase.cpp:
C++:
} else if (identifier == "playername") {
        node = new NpcBehaviourNode();
        node->type = BEHAVIOUR_TYPE_MESSAGE_PLAYERNAME;

Finally, also in behaviourdatabase.cpp:
C++:
    case BEHAVIOUR_TYPE_MESSAGE_PLAYERNAME: {
    std::string lowerMessage = asLowerCaseString(message);
   
    // Compare the lowercased message with the player's name
    if (lowerMessage == asLowerCaseString(player->getName())) {
        return 1; // Match found, return 1
    }
        return 2; // No...
To be honest I love when I find out people use my Sabrehaven. It is easy to forgot cipsoft npc syntax but I think you have to create this custom attribute yourself "name", I did create many custom of them so you should find out the examples easily. And yeah you need to edit behaviorDatabase.cpp

So in result you should want to do something like $1=Name -> "npc text"

I Think not many of guys here will want to provide you full example but when you solve this post your solution so I can press love on your post.
 
@Erikas Kontenis It's a great distribution to work from. I've had to do very little to get it working the way I need! I'm guessing this is the reason why in your GitHub commits, you left PoI at "99%" and did not add the Bureaucrats ;) since this function wasn't added

I was looking at the bank transfer behavior state for reference, since that is performing a similar function (name to string).

It looks like I would need to add something like this to behaviourdatabase.h:
C++:
BEHAVIOUR_TYPE_MESSAGE_PLAYERNAME, // return the player's name

Then something like this to behaviourdatabase.cpp:
C++:
} else if (identifier == "playername") {
        node = new NpcBehaviourNode();
        node->type = BEHAVIOUR_TYPE_PLAYERNAME;

The part that I'm stuck on is the actual function, lower down in behaviourdatabase.cpp. It should be something like this:
C++:
case BEHAVIOUR_TYPE_MESSAGE_PLAYERNAME {
        std::string lowerMessage = asLowerCaseString(message); //i think i need this
        player->getName()); //i think i need this too
    ???? //idk how to compare the two, this is where i need help
    }
 
Last edited:
TransferToPlayerNameState=$1 that is what you should want to do?

If TransferToPlayerNameState returns player name and $1 is player name which he just typed then TransferToPlayerNameState=$1 is true
Post automatically merged:

In your example:

Topic=1,playerName=$1 -> "Alright %N. Vocation?", Topic=2
 
I may have made it confusing with my last response, forgot to properly edit the stuff I copy and pasted over. I edited my previous post, but I was trying to add a new "case BEHAVIOUR_TYPE_MESSAGE_PLAYERNAME", I didn't think I could use the existing "case BEHAVIOUR_TYPE_MESSAGE_TRANSFERTOPLAYERNAME_STATE"

But are you saying I should be able to use the "case BEHAVIOUR_TYPE_MESSAGE_TRANSFERTOPLAYERNAME_STATE"?
 
No I am not saying u should reuse transfer to player name. What I say you should accomplish logic like this:
Topic=1,playerName=$1 -> "Alright %N. Vocation?", Topic=2

For testing you could even make:
Topic=1,"X X X"=$1 -> "Alright %N. Vocation?", Topic=2

To check that your equation is working correct in first place. So later all you need is to make "playerName" function return actual player name.
 
Some overcomplication going on here. No need for testing with "Topic=1,"X X X" or whatever. OP you're on the right track:

In behaviourdatabase.h:
C++:
BEHAVIOUR_TYPE_MESSAGE_PLAYERNAME, // return the player's name

Then in behaviourdatabase.cpp:
C++:
} else if (identifier == "playername") {
        node = new NpcBehaviourNode();
        node->type = BEHAVIOUR_TYPE_MESSAGE_PLAYERNAME;

Finally, also in behaviourdatabase.cpp:
C++:
    case BEHAVIOUR_TYPE_MESSAGE_PLAYERNAME: {
    std::string lowerMessage = asLowerCaseString(message);
   
    // Compare the lowercased message with the player's name
    if (lowerMessage == asLowerCaseString(player->getName())) {
        return 1; // Match found, return 1
    }
        return 2; // No match, return 2
    }

Then, for your NPC script:
Code:
Topic=1,PlayerName=1       -> "Alright %N. Vocation?", Topic=2

If you want the NPC to say something if the player spells their name wrong, then:
Code:
Topic=1,PlayerName=2       -> "Are you sure about that?"
Or whatever. Not sure what those skeleton NPCs say in RL if your name is wrong but you get the point.
 
Solution
Back
Top