Merge branch 'master' of ssh://mgg/mudlib-public
diff --git a/std/player/channel.c b/std/player/channel.c
index f1521f7..b29240d 100644
--- a/std/player/channel.c
+++ b/std/player/channel.c
@@ -68,7 +68,7 @@
+ (IS_LEARNER(this_object()) ? WIZARD_SHORTCUTS : ([])));
}
-static mixed _query_localcmds()
+static <int|string>** _query_localcmds()
{
return ({({"-","ChannelParser", 1, 0}),
({"ebene", "ChannelAdmin", 0, 0}),
@@ -76,9 +76,9 @@
});
}
-mixed RegisterChannels()
+string* RegisterChannels()
{
- mixed err;
+ string* err;
if(extern_call() &&
previous_object() != find_object(CHMASTER)) return;
c_status = 0;
@@ -96,10 +96,10 @@
return err;
}
-mixed RemoveChannels()
+string* RemoveChannels()
{
closure cl;
- mixed err=({});
+ string* err=({});
if(extern_call() &&
previous_object() != find_object(CHMASTER)) return;
if(!c_status) c_status = 1;
@@ -112,10 +112,9 @@
return err;
}
-varargs private string getName(mixed x, int fall) {
-
- mixed o = closurep(x) ? query_closure_object(x) : x;
- if(stringp(o) && sizeof(o) && (x = find_object(o)))
+varargs private string getName(string|object|closure x, int fall) {
+ string|object o = closurep(x) ? query_closure_object(x) : x;
+ if(stringp(o) && sizeof(o) && (x = find_object(o)))
o = x;
// Objekte
@@ -216,11 +215,12 @@
private void createList(string n, mixed a, mixed m, mixed l)
{
- int pos; string sh, *mem;
- if((pos = member(map(m_values(shortcut), #'lower_case/*'*/), n)) != -1)
+ int pos = member(map(m_values(shortcut), #'lower_case/*'*/), n);
+ string sh = "";
+ if(pos != -1)
sh = m_indices(shortcut)[pos];
- else sh = "";
- mem=map(a[I_MEMBER],#'getName/*'*/, WER);
+
+ string* mem=map(a[I_MEMBER],#'getName/*'*/, WER);
mem-=({"<MasteR>"});
l += ({ sprintf("%-12.12'.'s %c[%-1.1s] %|12.12' 's (%-|3' 'd) %-42.42s\n",
a[I_NAME], (member(m, n) != -1 ? '*' : ' '), sh,
@@ -235,9 +235,10 @@
private mixed getChannel(string ch)
{
- mixed ff;
- if(!sizeof(ch)) ch = QueryProp(P_STD_CHANNEL);
- if(shortcut && shortcut[ch]) ch = shortcut[ch];
+ if(!sizeof(ch))
+ ch = QueryProp(P_STD_CHANNEL);
+ if(shortcut && shortcut[ch])
+ ch = shortcut[ch];
return CHMASTER->find(ch, this_object());
}
@@ -340,7 +341,7 @@
}
else
{
- mixed list; list = ({});
+ string* list = ({});
if(cmd[1][<1] == '!')
l -= mkmapping(m_indices(l) - QueryProp(P_CHANNELS));
walk_mapping(l, #'createList/*'*/, QueryProp(P_CHANNELS), &list);
@@ -358,14 +359,13 @@
}
case '*':
{
- mixed hist; int amount;
- if(!pointerp(hist = CHMASTER->history(ch, this_object()))
- || !sizeof(hist))
+ mixed hist = CHMASTER->history(ch, this_object());
+ if(!pointerp(hist) || !sizeof(hist))
{
write("Es ist keine Geschichte fuer '"+ch+"' verfuegbar.\n");
return 1;
}
-
+
//(Zesstra) cmd hat offenbar immer 3 Elemente...
//bei -all* ({"","all*",""})
//bei -all*10 ({"","all*,"10"})
@@ -374,7 +374,7 @@
amount = to_int(cmd[2]);
else
amount=sizeof(hist);*/
- amount=to_int(cmd[2]);
+ int amount=to_int(cmd[2]);
if (amount <= 0 || amount >= sizeof(hist))
amount=sizeof(hist);
@@ -437,7 +437,7 @@
int ChannelAdmin(string args)
{
string n, descr, sh, cn;
- mixed pa, tmp;
+ mixed tmp;
args = _unparsed_args();
notify_fail("Benutzung: ebene <Abkuerzung>=<Ebene>\n"
" ebene <Abkuerzung>=\n"
@@ -552,7 +552,7 @@
write("Du stellst die Ebenen ab.\n");
return 1;
}
- pa = old_explode(args, " ");
+ string* pa = old_explode(args, " ");
if(!strstr("abkuerzungen", pa[0]))
{
string txt; txt = "";
diff --git a/std/room/kraeuter.c b/std/room/kraeuter.c
index 24f5193..92f4f56 100644
--- a/std/room/kraeuter.c
+++ b/std/room/kraeuter.c
@@ -9,15 +9,24 @@
#include <defines.h>
#include <living/combat.h> // Fuer P_FREE_HANDS
+public int AddPlantDetail(string filename);
+
// Standardwert von 2 h fuer vollstaendige Regeneration des Krautes.
// Einfaches Nachwachsen ist typischerweise die Haelfte davon.
#define STD_WACHSTUM 7200
#define BS(x) break_string(x, 78)
-// Struktur (6 Eintraege pro Kraut):
-// ([ filename : ({ Zeit_bis_nachgewachsen, Zeit_bis_komplett_regeneriert,
-// Kraut-IDs, Kraut-Adjektive, Kraut->Name(WER,1),
-// ID_des_Bewacher-NPCs }) ])
+// Struktur (7 Eintraege pro Kraut):
+struct plantinfo {
+ int regrow; // Zeit_bis_nachgewachsen
+ int regeneration; // Zeit_bis_komplett_regeneriert
+ int pickable; // per Standardkommanod pflueckbar?
+ string *ids; // Kraut-IDs
+ string *adj; // Kraut-Adjektive
+ string name; // Kraut->Name(WER,1)
+ string *guards; // ID_des_Bewacher-NPCs
+};
+// ([ filename : struct plantinfo ])
mapping plantMap = ([]);
// kann benutzt werden um schnell und einfach eine Pflanze in einem Raum
@@ -28,99 +37,102 @@
// 1 -> Erfolg; -1 -> filename ungueltig
varargs int AddPlant(string filename, string|string* npcId)
{
- mixed arr;
-
- // Dateiname nicht uebergeben? Dann tun wir erstmal gar nix.
- if (!stringp(filename))
+ // Eintrag und Details etc. hinzufuegen, wenn nicht erfolgreich, auch mit -1
+ // beenden.
+ if (AddPlantDetail(filename) == -1)
return -1;
- object ob=load_object(filename);
-
- // Wenn wir zu dem Kraut schon Daten haben (erkennbar an >2 Eintraegen),
- // werfen wir einen Fehler, damit das beim Laden des Raumes schon
- // erkannt wird.
- if (pointerp(arr=plantMap[filename]) && sizeof(arr)>2)
- raise_error("AddPlant(): "+filename+" already exists.\n");
- // IDs und Adjektive parsen und den Datensatz zusammenstellen
- string *ids = ob->Query(P_IDS, F_VALUE)-({ "Ding" });
- string *adj = ob->Query(P_ADJECTIVES, F_VALUE);
-
- if (!pointerp(arr) || sizeof(arr)<2)
- arr = ({0,0});
- if ( !npcId )
- npcId = ({});
- else if (stringp(npcId))
- npcId = ({npcId});
- plantMap[filename]=({arr[0], arr[1], ids, adj, ob->Name(WER, 1), npcId });
-
- // Details erzeugen aus Adjektiven und IDs
- adj = ob->QueryProp(P_NAME_ADJ);
-
- // aktuelles Geschlecht zwischenspeichern, wird spaeter wiederhergestellt
- int gender = Query(P_GENDER, F_VALUE);
- Set(P_GENDER, ob->Query(P_GENDER, F_VALUE), F_VALUE);
-
- // erzeugt fuer jede moegliche Kombination aus Adjektiv im Akkusativ
- // und ID des Krautes ein Detail.
- adj = map(adj, #'DeclAdj, WEN, 0);
+ struct plantinfo plant = plantMap[filename];
- string *det=({});
- foreach(string _id : ids) {
- foreach(string _adj : adj) {
- det += ({ _adj + _id });
- }
+ // es ist pflueckbar
+ plant->pickable = 1;
+
+ // Bewacher noch eintragen
+ if (npcId)
+ {
+ if (stringp(npcId))
+ plant->guards = ({npcId});
+ else
+ plant->guards = npcId;
}
-
- det += ids;
- // keine existierenden Details ueberschreiben
- det -= m_indices(Query(P_DETAILS, F_VALUE) || ([]));
- if (sizeof(det))
- AddDetail(det, ob->Query(PLANT_ROOMDETAIL, F_VALUE));
-
- // Eine Befehlsfunktion brauchen wir natuerlich auch.
+ // Eine Befehlsfunktion brauchen wir dann natuerlich auch.
AddCmd(({"pflueck", "pfluecke", "ernte"}), "_pfluecken");
-
- return 1;
+
+ // erfolgreich fertig
+ return 1;
}
// Wenn jemand per Hand das Plantdetail hinzufuegen moechte...
// z.B. bei Verwendung von GetPlant() anstelle von AddPlant()
-void AddPlantDetail(string filename)
+// Im Gegensatz zu AddPlant() fuegt es kein Kommando zum Pfluecken hinzu und
+// traegt keine Bewacher ein.
+// 1 -> Erfolg; -1 -> filename ungueltig
+public int AddPlantDetail(string filename)
{
- // Pfad in Objektpointer wandeln
+ // Dateiname nicht uebergeben? Dann tun wir erstmal gar nix.
+ if (!stringp(filename))
+ return -1;
object ob=load_object(filename);
-
- // Details erzeugen
- string *det = ({});
- string *ids = ob->Query(P_IDS, F_VALUE)-({ "Ding" });
- string *adj = ob->QueryProp(P_NAME_ADJ);
+
+ // Wenn wir zu dem Kraut schon Daten haben, werfen wir einen Fehler, damit
+ // das beim Laden des Raumes schon erkannt wird.
+ struct plantinfo plant = plantMap[filename];
+ if (structp(plant))
+ raise_error("AddPlant(): "+filename+" already exists.\n");
+
+ plant = (<plantinfo>);
+ // IDs und Adjektive parsen und den Datensatz zusammenstellen
+ plant->ids = ob->Query(P_IDS, F_VALUE)-({ "Ding" });
+ plant->adj = ob->Query(P_ADJECTIVES, F_VALUE);
+ // Keine Bewacher
+ plant->guards = ({});
+ // Ausserdem ist es nicht pflueckbar per Standardkommando (pickable nicht
+ // gesetzt)
+ // Und eintragen
+ plantMap[filename] = plant;
+
+ // Details erzeugen aus Adjektiven und IDs
+ string *name_adj = ob->QueryProp(P_NAME_ADJ);
+
// aktuelles Geschlecht zwischenspeichern, wird spaeter wiederhergestellt
- int gender=Query(P_GENDER, F_VALUE);
- Set(P_GENDER, ob->Query(P_GENDER, F_VALUE));
+ int gender = Query(P_GENDER, F_VALUE);
+ Set(P_GENDER, ob->Query(P_GENDER, F_VALUE), F_VALUE);
+
// erzeugt fuer jede moegliche Kombination aus Adjektiv im Akkusativ
// und ID des Krautes ein Detail.
- adj = map(adj, #'DeclAdj, WEN, 0);
- foreach(string _id : ids) {
- foreach(string _adj : adj) {
+ name_adj = map(name_adj, #'DeclAdj, WEN, 0);
+
+ // Geschlecht zuruecksetzen
+ Set(P_GENDER, gender, F_VALUE);
+
+ string *det=({});
+ foreach(string _id : plant->ids) {
+ foreach(string _adj : name_adj) {
det += ({ _adj + _id });
}
}
- AddDetail(det+ids, ob->Query(PLANT_ROOMDETAIL, F_VALUE));
- // Geschlecht zuruecksetzen
- Set(P_GENDER, gender, F_VALUE);
+
+ det += plant->ids;
+ // keine existierenden Details ueberschreiben
+ det -= m_indices(Query(P_DETAILS, F_VALUE) || ([]));
+ if (sizeof(det))
+ AddDetail(det, ob->Query(PLANT_ROOMDETAIL, F_VALUE));
+
+ return 1;
}
// Prueft, ob die Pflanze zu "filename" in diesem Raum schon nachgewachsen
// ist.
protected int CheckPlant(string filename)
{
- mixed arr=plantMap[filename];
- if (!pointerp(arr) || sizeof(arr)<2) {
- arr=plantMap[filename]=({ 0, 0 });
- }
+ struct plantinfo plant = plantMap[filename];
+ // Wenn es keinen Eintrag gibt, gibt es offenbar keine Pflanze
+ if (!structp(plant))
+ return 0;
+
// Solange die Zeit arr[0] noch nicht erreicht ist, ist das Kraut nicht
// nachgewachsen, dann gibt es gar nix.
- return (time()>arr[0]);
+ return (time() > plant->regrow);
}
// Moechte man AddPlant() nicht benutzen, weil man die Pflanze nicht einfach
@@ -130,32 +142,34 @@
// nachgewachsen.
object GetPlant(string filename)
{
- int *arr=plantMap[filename];
- if (!pointerp(arr) || sizeof(arr)<2)
- {
- arr=plantMap[filename]=({ 0, 0 });
- }
- // arr[0] enthaelt den Zeitpunkt, wann das Kraut nachgewachsen ist,
- int nachgewachsen = arr[0];
- // arr[1] denjenigen, wann es vollstaendig regeneriert ist.
- int regeneriert = arr[1];
+ struct plantinfo plant = plantMap[filename];
+ // Wenn es keinen Eintrag gibt, gibt es offenbar keine Pflanze
+ if (!structp(plant))
+ return 0;
+
+ // regrow enthaelt den Zeitpunkt, wann das Kraut nachgewachsen ist,
+ // regeneration denjenigen, wann es vollstaendig regeneriert ist.
// Vor dem Nachgewachsen-Zeitpunkt kann man gar nix ernten.
- if (time()<nachgewachsen) return 0; // noch nicht nachgewachsen
+ if (time() < plant->regrow)
+ return 0; // noch nicht nachgewachsen
// Restzeit bis zur vollstaendigen Regeneration.
- regeneriert-=time();
-
+ int regeneriert = plant->regeneration - time();
+
// Wenn vollstaendig regeneriert, ist STD_WACHSTUM die neue Zeit bis zur
- // Regeneration. Wenn noch nicht vollstaendig regenriert, Restzeit
+ // Regeneration. Wenn noch nicht vollstaendig regeneriert, Restzeit
// verdoppeln und STD_WACHSTUM nochmal drauf addieren.
- regeneriert = (regeneriert<=0 ? STD_WACHSTUM
- : (regeneriert*2)+STD_WACHSTUM);
- // nachgewachsen ist die halbe Regenerationszeit
- arr[0]=nachgewachsen=time()+(regeneriert/2);
- // Zeit voelliger Regeneration
- arr[1]=regeneriert+=time();
-
+ if (regeneriert<=0)
+ regeneriert = STD_WACHSTUM;
+ else
+ regeneriert = (regeneriert*2)+STD_WACHSTUM;
+
+ // Zeitpunkt des Nachwachsen ist die halbe Regenerationszeit
+ plant->regrow = time() + (regeneriert/2);
+ // Zeitpunkt voelliger Regeneration
+ plant->regeneration = regeneriert + time();
+
return clone_object(filename);
}
@@ -170,17 +184,17 @@
mixed ids = Query(P_IDS, F_VALUE);
mixed adj = Query(P_ADJECTIVES, F_VALUE);
- foreach(string key, mixed krautinfo : plantMap)
+ foreach(string key, struct plantinfo plant : plantMap)
{
- if ( sizeof(krautinfo) != 6 )
+ if ( !structp(plant) || !plant->pickable )
continue;
-
+
// IDs und Adjektive des Krautes kopieren
- Set(P_IDS, krautinfo[2], F_VALUE);
- Set(P_ADJECTIVES, krautinfo[3], F_VALUE);
+ Set(P_IDS, plant->ids, F_VALUE);
+ Set(P_ADJECTIVES, plant->adj, F_VALUE);
// Syntaxpruefung wird dann mit id() gemacht.
- if (id(str))
+ if (id(str))
{
object ob;
object bewacher;
@@ -188,14 +202,14 @@
// Liste der eingetragenen Bewacher-IDs durchlaufen und pruefen, ob
// mindestens einer davon anwesend ist.
- foreach( string npcId : krautinfo[5] )
+ foreach( string npcId : plant->guards )
{
bewacher = present(npcId, ME);
if (objectp(bewacher))
break;
}
-
- if ( !PL->QueryProp(P_FREE_HANDS) )
+
+ if ( !PL->QueryProp(P_FREE_HANDS) )
{
tell_object(PL, BS("Du hast keine Hand frei, um etwas pfluecken "
"zu koennen."));
@@ -208,7 +222,7 @@
"zunaechst um "+bewacher->QueryPronoun(WEN)+" kuemmern."));
}
// Wenn GetPlant() ein Objekt liefert, kann was gepflueckt werden.
- else if ( objectp(ob=GetPlant(key)) )
+ else if ( objectp(ob=GetPlant(key)) )
{
if ( ob->move(PL, M_GET) == MOVE_OK )
{
@@ -225,7 +239,7 @@
// Wenn alles nicht, dann ist das Kraut noch nicht wieder da.
else
{
- write(BS(krautinfo[4]+" ist noch nicht reif genug "
+ write(BS(plant->name+" ist noch nicht reif genug "
+"und muss erst noch etwas wachsen."));
break;
}