Added public files
Roughly added all public files. Probably missed some, though.
diff --git a/std/gilden_ob.c b/std/gilden_ob.c
new file mode 100644
index 0000000..6805acc
--- /dev/null
+++ b/std/gilden_ob.c
@@ -0,0 +1,462 @@
+// MorgenGrauen MUDlib
+//
+// gilden_ob.c -- Basisfunktionen einer Gilde
+//
+// $Id: gilden_ob.c 8433 2013-02-24 13:47:59Z Zesstra $
+#pragma strict_types
+#pragma save_types
+#pragma no_shadow
+#pragma no_clone
+#pragma range_check
+#pragma pedantic
+
+inherit "/std/restriction_checker";
+#include <properties.h>
+#include <attributes.h>
+#include <new_skills.h>
+#include <defines.h>
+#include <player/fao.h>
+#include <wizlevels.h>
+
+void create() {
+ // P_GUILD_SKILLS sollte nicht direkt von aussen manipuliert werden...
+ SetProp(P_GUILD_SKILLS,([]));
+ Set(P_GUILD_SKILLS,PROTECTED,F_MODE_AS);
+}
+
+mapping _query_guild_skills() {
+ // eine Kopie zurueckliefern, um versehentliche Aenderungen des
+ // Originalmappings in der Gilde zu vermeiden.
+ // Darf nicht ohne weiteres entfernt werden, da es hier im File Code gibt,
+ // der sich auf die Kopie verlaesst.
+ return(deep_copy(Query(P_GUILD_SKILLS)));
+}
+
+string GuildName() {
+ //Gilden muessen Blueprints sein, so. ;-)
+ return object_name(this_object())[8..];
+}
+
+varargs int
+IsGuildMember(object pl) {
+ string plg;
+
+ if (!pl && !(pl=this_player()))
+ return 0;
+ if (!(plg=(string)pl->QueryProp(P_GUILD)))
+ return 0;
+ if (GuildName()!=plg) {
+ _notify_fail("Du gehoerst dieser Gilde nicht an!\n");
+ return 0;
+ }
+ return 1;
+}
+
+int check_cond(mixed cond) {
+ string res;
+
+ if (intp(cond)) {
+ _notify_fail("Dir fehlt noch die noetige Erfahrung. "+
+ "Komm spaeter wieder.\n");
+ return (this_player()->QueryProp(P_XP)>=cond);
+ }
+ if (mappingp(cond)) {
+ res=check_restrictions(this_player(),cond);
+ if (!stringp(res)) return 1;
+ _notify_fail(res);
+ return 0;
+ }
+ return 1;
+}
+
+int can_advance() {
+ int lv;
+ mapping lvs;
+
+ if (!(lv=(int)this_player()->QueryProp(P_GUILD_LEVEL))) return 1;
+ if (!(lvs=QueryProp(P_GUILD_LEVELS))) return 0;
+ return check_cond(lvs[lv+1]); // Bedingung fuer naechsten Level testen.
+}
+
+void adjust_title(object pl) {
+ int lv;
+ mixed ti;
+
+
+ if (!pl ||
+ !(lv=(int)pl->QueryProp(P_GUILD_LEVEL)))
+ return;
+ switch((int)pl->QueryProp(P_GENDER)) {
+ case MALE:
+ ti=QueryProp(P_GUILD_MALE_TITLES);
+ break;
+ case FEMALE:
+ ti=QueryProp(P_GUILD_FEMALE_TITLES);
+ break;
+ default:
+ return;
+ }
+ if (mappingp(ti))
+ ti=ti[lv];
+ if (stringp(ti))
+ pl->SetProp(P_GUILD_TITLE,ti);
+
+ // Spielertitel nullen, damit der Gildentitel angezeigt wird.
+ if (!IS_SEER(pl) && !FAO_HAS_TITLE_GIFT(pl))
+ pl->SetProp(P_TITLE,0);
+}
+
+void do_advance() {
+ int lv;
+
+ lv=this_player()->QueryProp(P_GUILD_LEVEL)+1;
+ if (lv<1) lv=1;
+ this_player()->SetProp(P_GUILD_LEVEL,lv);
+ adjust_title(this_player());
+}
+
+int try_advance() {
+ if (can_advance()) {
+ if (IsGuildMember(this_player()))
+ do_advance();
+ return 1;
+ }
+ return 0;
+}
+
+int beitreten() {
+ string res;
+ int erg;
+
+ if (res=check_restrictions(this_player(),QueryProp(P_GUILD_RESTRICTIONS))) {
+ // Werden die Beitrittsbedingungen erfuellt?
+ printf("Du kannst dieser Gilde nicht beitreten.\nGrund: %s",res);
+ return -3;
+ }
+ if (erg=(int)GUILDMASTER->beitreten()) {
+ if (erg<0)
+ return erg;
+ if (!(this_player()->QueryProp(P_GUILD_LEVEL)))
+ try_advance(); // Level 1 wird sofort vergeben
+ return 1;
+ }
+ return 0;
+}
+
+varargs int austreten(int loss) {
+ return (int)GUILDMASTER->austreten(loss);
+}
+
+int bei_oder_aus_treten(string str) {
+ if (!str) return 0;
+ if (sizeof(regexp(({lower_case(str)}),
+ "\\<aus\\>.*gilde\\>.*\\<aus\\>")))
+ return austreten();
+ if (sizeof(regexp(({lower_case(str)}),
+ "(gilde\\>.*\\<bei\\>|\\<in\\>.*gilde\\>.*\\<ein\\>)")))
+ return beitreten();
+ return 0;
+}
+
+varargs int
+AddSkill(string sname, mapping ski) {
+ mapping skills;
+
+ if (!sname)
+ return 0;
+
+ // per Query() abfragen, hier ist keine Kopie noetig.
+ if (!mappingp(skills=Query(P_GUILD_SKILLS))) {
+ skills=([]);
+ SetProp(P_GUILD_SKILLS,skills);
+ }
+
+ if (!mappingp(ski))
+ ski=([]);
+ else
+ //Zur Sicherheit Kopie erstellen, wer weiss, was der Eintragende noch
+ //mit seinem Mapping macht...
+ ski=deep_copy(ski);
+
+ if (!stringp(ski[SI_SKILLFUNC]))
+ // Wenn keine Funktion angegeben ist, Funktionsname=Skillname
+ ski[SI_SKILLFUNC]=sname;
+
+ // Gilden-Offsets addieren
+ ski=AddSkillMappings(QueryProp(P_GLOBAL_SKILLPROPS),ski);
+
+ // Skill setzen.
+ skills[sname]=ski;
+ //SetProp() unnoetig, da oben per Query() das Originalmapping erhalten
+ //wurde.
+ //SetProp(P_GUILD_SKILLS,skills);
+ return 1;
+}
+
+
+varargs int
+AddSpell(string verb, mapping ski) {
+ mapping skills;
+
+ if (!verb)
+ return 0;
+ if (!mappingp(ski))
+ ski=([]);
+
+ if (!stringp(ski[SI_SPELLBOOK]) &&
+ !stringp(ski[SI_SPELLBOOK]=QueryProp(P_GUILD_DEFAULT_SPELLBOOK)))
+ // Wenn kein Spellbook angegeben ist muss ein
+ // Default-Spellbook angegeben sein, sonst Fehler
+ return 0;
+ if (file_size(SPELLBOOK_DIR+ski[SI_SPELLBOOK]+".c")<0)
+ return 0; // Spellbook sollte auch existieren...
+
+ return AddSkill(lower_case(verb),ski);
+}
+
+mapping QuerySkill(string skill) {
+ mapping ski;
+
+ // Abfrage per Query(), da vielleicht nur ein Skill gewuenscht
+ // wird und daher die komplette Kopie des Spellmappings in der Query-Methode
+ // unnoetig ist.
+ if (!skill
+ || !(ski=Query(P_GUILD_SKILLS, F_VALUE))
+ || !(ski=ski[skill])) // Gildenspezifische Skilleigenschaften
+ return 0;
+ // hier aber dann natuerlich eine Kopie erstellen. ;-)
+ return(deep_copy(ski));
+}
+
+mapping QuerySpell(string spell) {
+ mapping ski,ski2;
+ string spellbook,sfunc;
+
+ // QuerySkill() hier und QuerySpell() im Spellbook liefern Kopien der
+ // Skillmappings zurueck, Kopieren hier daher unnoetig.
+ if (!spell
+ || !(ski=QuerySkill(spell))
+ || !(spellbook=ski[SI_SPELLBOOK]))
+ return 0;
+ if (!(sfunc=ski[SI_SKILLFUNC]))
+ sfunc=spell;
+ spellbook=SPELLBOOK_DIR+spellbook;
+ if (!(ski2=(mapping)(spellbook->QuerySpell(sfunc))))
+ return 0;
+ return AddSkillMappings(ski2,ski); // Reihenfolge wichtig!
+ // Die Gilde kann Spelleigenschaften neu definieren!
+}
+
+varargs int
+UseSpell(object caster, string spell, mapping sinfo) {
+ mapping ski;
+ string spellbook;
+
+ if (!caster
+ || !spell
+ || !(ski=QuerySkill(spell)) // Existiert dieser Spell in dieser Gilde?
+ || !(spellbook=ski[SI_SPELLBOOK])) // Spellbook muss bekannt sein
+ return 0;
+ if (sinfo)
+ ski+=sinfo;
+ spellbook=SPELLBOOK_DIR+spellbook;
+ // printf("%O %O %O %O\n",spellbook,caster,spell,ski);
+ return (int)spellbook->UseSpell(caster,spell,ski);
+}
+
+static int
+InitialSkillAbility(mapping ski, object pl) {
+ if (!ski || !pl) return 0;
+ return (300*GetOffset(SI_SKILLLEARN,ski,pl)+
+ (200*(int)pl->QueryAttribute(A_INT)*
+ GetFactor(SI_SKILLLEARN,ski,pl))/100);
+}
+
+int
+SkillListe(int what) {
+ int res;
+ // Querymethode erstellt Kopie (wichtig!)
+ mapping allskills=QueryProp(P_GUILD_SKILLS);
+ string *skills=({});
+ string *spells=({});
+
+ if (!mappingp(allskills) || !sizeof(allskills))
+ return 0;
+
+ foreach(string s, mapping sdata: &allskills) {
+ // Lernlevel ermitteln und speichern.
+ mapping tmp=QuerySpell(s);
+ // wenn nix gefunden, dann ist es ein Skill, sonst ein Spell.
+ if (tmp) {
+ spells += ({s});
+ // das Spellbook hat im Zweifel das SI_SKILLINFO
+ sdata[SI_SKILLINFO] = tmp[SI_SKILLINFO];
+ }
+ else {
+ // SI_SKILLINFO steht in diesem Fall schon in sdata...
+ tmp = QuerySkill(s);
+ skills += ({s});
+ }
+ // gucken, obs nen Lernlevel gibt und einfach in sdata schreiben
+ if ( (tmp=tmp[SI_SKILLRESTR_LEARN]) )
+ sdata["_restr_level"] = tmp[P_LEVEL];
+ }
+
+ // jetzt sortieren.
+ closure cl = function int (string a, string b)
+ { return allskills[a]["_restr_level"] > allskills[b]["_restr_level"]; };
+ if (what & 0x01)
+ spells = sort_array(spells, cl);
+ if (what & 0x02)
+ skills = sort_array(skills, cl);
+
+ // und ausgeben
+ cl = function void (string *list)
+ {
+ string tmp="";
+ int lvl;
+ foreach(string sp: list) {
+ lvl = allskills[sp]["_restr_level"];
+ if (lvl>0)
+ tmp += sprintf("%-20s %d\n",sp,lvl);
+ else
+ tmp += sprintf("%-20s\n",sp);
+ if (allskills[sp][SI_SKILLINFO])
+ tmp += break_string(allskills[sp][SI_SKILLINFO], 78,
+ " ");
+ }
+ tell_object(PL, tmp);
+ };
+
+ if ((what & 0x01) && sizeof(spells)) {
+ res = 1;
+ tell_object(PL,sprintf(
+ "Du kannst versuchen, folgende Zaubersprueche zu lernen:\n"
+ "%-20s %-3s\n","Zauberspruch","Spielerstufe"));
+ funcall(cl, spells);
+ tell_object(PL,break_string(
+ "Du kannst einen Zauberspruch mit dem Kommando \"lerne\", gefolgt "
+ "vom Zauberspruchnamen lernen.",78));
+ }
+ if ((what & 0x02) && sizeof(skills)) {
+ res = 1;
+ tell_object(PL,sprintf(
+ "Du kannst versuchen, folgende Faehigkeiten zu erwerben:\n"
+ "%-20s %-3s\n","Faehigkeit","Spielerstufe"));
+ funcall(cl, skills);
+ }
+
+ return res;
+}
+
+varargs int
+LearnSpell(string spell,object pl) {
+ mapping ski,restr;
+ string res;
+ mixed learn_initfunc;
+ int abil,diff;
+
+ // Wenn kein pl gesetzt ist, nehmen wir this_player(), das ist der
+ // Normalfall.
+ if (!pl)
+ pl=this_player();
+ if (!IsGuildMember(pl)) {
+ _notify_fail("Du gehoerst dieser Gilde nicht an!\n");
+ return 0;
+ }
+ _notify_fail("Was moechtest Du lernen?\n");
+ if (!spell)
+ return SkillListe(0x01);
+ spell=lower_case(spell);
+ if (!(ski=QuerySpell(spell)))
+ return 0;
+ if (pl->QuerySkill(spell)) {
+ _notify_fail("Du kannst diesen Spruch doch schon!\n");
+ return 0;
+ }
+ if ((restr=ski[SI_SKILLRESTR_LEARN])
+ && (res=check_restrictions(pl,restr))) {
+ printf("Du kannst diesen Spruch noch nicht lernen.\nGrund: %s",res);
+ return 1;
+ }
+ abil=InitialSkillAbility(ski,pl);
+ if (abil<1) abil=1;
+ if (abil>7500) abil=7500;
+ write("Du lernst einen neuen Zauberspruch.\n");
+ if (!(diff=GetFValueO(SI_DIFFICULTY,ski,pl)))
+ diff=GetFValueO(SI_SPELLCOST,ski,pl);
+ pl->ModifySkill(spell,abil,diff);
+ return 1;
+}
+
+int
+LearnSkill(string skill) {
+ mapping ski,restr;
+ object pl;
+ string res;
+ mixed learn_initfunc;
+ int abil,diff;
+
+ if (!IsGuildMember(pl=this_player())) {
+ _notify_fail("Du gehoerst dieser Gilde nicht an!\n");
+ return 0;
+ }
+ _notify_fail("Was moechtest Du lernen?\n");
+ if (!skill)
+ return SkillListe(0x02);
+ skill=capitalize(skill);
+ if (!(ski=QuerySkill(skill)))
+ return 0;
+ if (pl->QuerySkill(skill)) {
+ _notify_fail("Du hast diese Faehigkeit doch schon!\n");
+ return 0;
+ }
+ if ((restr=ski[SI_SKILLRESTR_LEARN])
+ && (res=check_restrictions(pl,restr))) {
+ printf("Du kannst diese Faehigkeit noch nicht erwerben.\nGrund: %s",res);
+ return 1;
+ }
+ abil=InitialSkillAbility(ski,pl);
+ if (!abil) abil=1;
+ if (abil>MAX_ABILITY) abil=MAX_ABILITY;
+ if (abil<-MAX_ABILITY) abil=-MAX_ABILITY;
+ write("Du erwirbst eine neue Faehigkeit.\n");
+ diff=GetFValueO(SI_DIFFICULTY,ski,pl);
+ pl->ModifySkill(skill,abil,diff);
+ return 1;
+}
+
+int GuildRating(object pl)
+{
+ mapping ski;
+ string *sk;
+ int i, cnt, sum;
+ closure qsa;
+
+ if (!IsGuildMember(pl)||!query_once_interactive(pl))
+ return 0;
+
+ if (!(ski = QueryProp(P_GUILD_SKILLS)) ||
+ !(qsa = symbol_function("QuerySkillAbility",pl)))
+ return 0;
+
+ sk = m_indices(ski);
+ cnt = sizeof(ski);
+
+ for (i=cnt-1, sum=0; i>=0; i--)
+ sum += funcall(qsa, sk[i]);
+
+ sum = sum/cnt;
+ if (sum < 0)
+ sum = 0;
+ else if (sum > MAX_ABILITY)
+ sum = MAX_ABILITY;
+
+ return (int)pl->SetProp(P_GUILD_RATING, sum);
+}
+
+// Wird von /std/player/quest.c aufgerufen, wenn Quest geloest.
+// (Jedes mal - nicht nur beim ersten mal.)
+// Ist zum selbst-ueberschreiben gedacht, sollte aber definiert sein.
+void NotifyGiveQuest(object pl, string key){ }
+