Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Server Code Submissions

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #1  
Old 03-07-2009, 12:54 PM
realityincarnate
Developer
 
Join Date: Dec 2007
Posts: 122
Default Learning Languages

This fix allows players to teach each other languages while grouped. It only works while grouped and in the same zone. I think the rate of learning feels about right, but it could be tinkered with. I also set the rate to be modified by the SkillUpModifier rule.

Can anyone point me to a good XS reference? I needed to modify the perl_groups code this time, and while I was able to get most of the idea by looking at other parts of the code, this part is pretty foreign to me.

Here's the diff, against R373
Code:
Index: zone/client.cpp
===================================================================
--- zone/client.cpp	(revision 373)
+++ zone/client.cpp	(working copy)
@@ -744,7 +744,7 @@
 
 		Group* group = GetGroup();
 		if(group != NULL) {
-			group->GroupMessage(this,(const char*) message);
+			group->GroupMessage(this,language,(const char*) message);
 		}
 		break;
 	}
@@ -920,6 +920,11 @@
 	if (language < MAX_PP_LANGUAGE) {
 		cm->skill_in_language = m_pp.languages[language];
 		cm->language = language;
+		if ((chan_num == 2) && (language != 0)) {	// for group messages not in common, check for language skill up
+			int SenderSkill = entity_list.GetClientByName(from)->m_pp.languages[language];
+			if ((m_pp.languages[language] <= SenderSkill) && (from != this->GetName() )) 
+				CheckLanguageSkillIncrease(language, SenderSkill);
+		}
 	}
 	else {
 		cm->skill_in_language = 100;
@@ -1920,6 +1925,25 @@
 	return false;
 }
 
+void Client::CheckLanguageSkillIncrease(int8 langid, int8 TeacherSkill) {
+	if (langid >= MAX_PP_LANGUAGE)
+		return;		// do nothing if langid is an invalid language
+
+	int LangSkill = m_pp.languages[langid];		// get current language skill
+
+	if (LangSkill < 100) {	// if the language isn't already maxed
+		sint16 Chance = 5 + ((TeacherSkill - LangSkill)/10);	// greater chance to learn if teacher's skill is much higher than yours
+		Chance = (Chance * RuleI(Character, SkillUpModifier)/100);
+
+		if(MakeRandomFloat(0,100) < Chance) {	// if they make the roll
+			SetLanguageSkill(langid, LangSkill+1);	// increase the language skill by 1
+			_log(SKILLS__GAIN, "Language %d at value %d successfully gain with %.4f%%chance", langid, LangSkill, Chance);
+		} 
+		else
+			_log(SKILLS__GAIN, "Language %d at value %d failed to gain with %.4f%%chance", langid, LangSkill, Chance);
+	}
+}
+
 bool Client::HasSkill(SkillType skill_id) const {
 	return((GetSkill(skill_id) > 0) && CanHaveSkill(skill_id));
 }
Index: zone/client.h
===================================================================
--- zone/client.h	(revision 373)
+++ zone/client.h	(working copy)
@@ -550,6 +550,7 @@
 	void CheckSpecializeIncrease(int16 spell_id);
 	void CheckSongSkillIncrease(int16 spell_id);
 	bool	CheckIncreaseSkill(SkillType skillid, int chancemodi = 0);
+	void	CheckLanguageSkillIncrease(int8 langid, int8 TeacherSkill);
 	void    SetLanguageSkill(int langid, int value);
 	void	SetHoTT(int32 mobid);
 
Index: zone/groups.cpp
===================================================================
--- zone/groups.cpp	(revision 373)
+++ zone/groups.cpp	(working copy)
@@ -664,14 +664,14 @@
 	return false;
 }
 
-void Group::GroupMessage(Mob* sender, const char* message) {
+void Group::GroupMessage(Mob* sender, int8 language, const char* message) {
 	uint32 i;
 	for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
 		if(!members[i])
 			continue;
 
 		if (members[i]->IsClient() && members[i]->CastToClient()->GetFilter(FILTER_GROUP)!=0)
-			members[i]->CastToClient()->ChannelMessageSend(sender->GetName(),members[i]->GetName(),2,0,message);
+			members[i]->CastToClient()->ChannelMessageSend(sender->GetName(),members[i]->GetName(),2,language,message);
 		#ifdef IPC
 		if (members[i]->CastToNPC()->IsInteractive() && members[i] != sender)
 			members[i]->CastToNPC()->InteractiveChat(2,1,message,(sender->GetTarget() != NULL) ? sender->GetTarget()->GetName():sender->GetName(),sender);
Index: zone/groups.h
===================================================================
--- zone/groups.h	(revision 373)
+++ zone/groups.h	(working copy)
@@ -68,7 +68,7 @@
 	void	CastGroupSpell(Mob* caster,uint16 spellid);
 	void	GroupBardPulse(Mob* caster,uint16 spellid);
 	void	SplitExp(uint32 exp, Mob* other);
-	void	GroupMessage(Mob* sender,const char* message);
+	void	GroupMessage(Mob* sender,int8 language,const char* message);
 	void	GroupMessage_StringID(Mob* sender, int32 type, int32 string_id, const char* message,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0, int32 distance = 0);
 	int32	GetTotalGroupDamage(Mob* other);
 	void	SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter = NULL);
Index: zone/perl_groups.cpp
===================================================================
--- zone/perl_groups.cpp	(revision 373)
+++ zone/perl_groups.cpp	(working copy)
@@ -168,12 +168,13 @@
 XS(XS_Group_GroupMessage)
 {
 	dXSARGS;
-	if (items != 3)
-		Perl_croak(aTHX_ "Usage: Group::GroupMessage(THIS, sender, message)");
+	if ((items != 3) && (items != 4))	// the 3 item version is kept for backwards compatability
+		Perl_croak(aTHX_ "Usage: Group::GroupMessage(THIS, sender, language, message)");
 	{
 		Group *		THIS;
 		Mob*		sender;
-		char*		message = (char *)SvPV_nolen(ST(2));
+		int8		language;
+		char*		message;
 
 		if (sv_derived_from(ST(0), "Group")) {
 			IV tmp = SvIV((SV*)SvRV(ST(0)));
@@ -193,7 +194,17 @@
 		if(sender == NULL)
 			Perl_croak(aTHX_ "sender is NULL, avoiding crash.");
 
-		THIS->GroupMessage(sender, message);
+		if (items == 4) {
+			language = (int8)SvUV(ST(2));
+			if ((language >= MAX_PP_LANGUAGE) || (language < 0))
+				language = 0;
+			message = (char *)SvPV_nolen(ST(3));
+			THIS->GroupMessage(sender, language, message);
+		}
+		else {	// if no language is specificed, send it in common
+			message = (char *)SvPV_nolen(ST(2));
+			THIS->GroupMessage(sender,0, message);
+		}
 	}
 	XSRETURN_EMPTY;
 }
Reply With Quote
 

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 08:51 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3