MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame^] | 1 | // (c) 2003 by Padreic (padreic@mg.mud.de) |
| 2 | // |
| 3 | // Es kann bestimmte Laeden zum Handeln von Kraeutern geben. |
| 4 | // Zunaechst einmal gibt es einen in der Dunkelelfengilde. |
| 5 | // Hier koennen Kraeuter ge- und verkauft werden. |
| 6 | // Grundsaetzlich kann es beliebig viele kraeuterkundige |
| 7 | // Haendler geben, eine kurze Absprache waere jedoch von Vorteil. |
| 8 | |
| 9 | // Der Laden erweitert die room/shop Funktionen. |
| 10 | // Zur Verwendung muss dieser noch mit einem std/room kombiniert |
| 11 | // werden. Dies erlaubt die Verwendung von eigenen Standardraeumen oder |
| 12 | // Kombination mit Kneipen. |
| 13 | |
| 14 | inherit "/std/room/shop"; |
| 15 | |
| 16 | #define NEED_PROTOTYPES |
| 17 | |
| 18 | #include <items/kraeuter/kraeuter.h> |
| 19 | #include <properties.h> |
| 20 | |
| 21 | // Flag, das im reset() das Speichern ausloest, wenn es gesetzt ist. |
| 22 | static int need_save; |
| 23 | static int basisvalue=400; // gibt den _Durchschnittswert_ eines Krauts an |
| 24 | static int maxvalue=10000; // bestimmt den max. Wert aller Kraeuter |
| 25 | |
| 26 | // Enthaelt fuer jede PlantID einen Zaehler, der angibt, wieviel von dem |
| 27 | // jeweiligen Kraut verkauft wurde. |
| 28 | // private int *count=({}); |
| 29 | |
| 30 | // Summe ueber alle Eintraege in count |
| 31 | // private int sum; |
| 32 | |
| 33 | protected void create() |
| 34 | { |
| 35 | if (object_name(this_object()) == __FILE__[0..<3]) |
| 36 | { |
| 37 | set_next_reset(-1); |
| 38 | return; |
| 39 | } |
| 40 | ::create(); |
| 41 | |
| 42 | SetProp(P_BUY_ONLY_PLANTS,1); |
| 43 | /* |
| 44 | seteuid(getuid()); // wird zum speichern benötigt |
| 45 | int si=sizeof(count); |
| 46 | // fuer jede PlantID einen Eintrag anlegen, d.h. wenn in count noch |
| 47 | // nicht genug vorhanden sind, werden fehlende Eintraege ergaenzt. |
| 48 | if (si<PLANTCOUNT) |
| 49 | count=count+allocate(PLANTCOUNT-si); |
| 50 | */ |
| 51 | } |
| 52 | |
| 53 | protected void create_super() |
| 54 | { |
| 55 | set_next_reset(-1); |
| 56 | } |
| 57 | |
| 58 | static string sell_obj_only_plants(object ob, int short) |
| 59 | { |
| 60 | if (!IS_PLANT(ob)) |
| 61 | return "Tut mir leid, damit kann ich nichts anfangen."; |
| 62 | // es werden nur Kraeuter angekauft, die legal geclont wurden, |
| 63 | // d.h. im entsprechenden Master ordentlich eingetragen wurden! |
| 64 | if (ob->QueryPlantId()<=0) |
| 65 | return ob->Name(WER, 2)+" ist illegal auf die Welt gekommen. Ich darf " |
| 66 | +ob->QueryPronoun(WEN)+" leider nicht annehmen."; |
| 67 | return ::sell_obj(ob, short); |
| 68 | } |
| 69 | |
| 70 | static string sell_obj(object ob, int short) |
| 71 | { |
| 72 | // es werden nur Kraeuter angekauft, die legal geclont wurden, |
| 73 | // d.h. im entsprechenden Master ordentlich eingetragen wurden! |
| 74 | if (IS_PLANT(ob) && ob->QueryPlantId()<=0) |
| 75 | return "Hm, "+ob->Name(WER, 2)+" stammt aber aus einer sehr dubiosen " |
| 76 | "Quelle. Ich kann "+ob->QueryPronoun(WEN)+" leider nicht annehmen."; |
| 77 | if (QueryProp(P_BUY_ONLY_PLANTS)) |
| 78 | return sell_obj_only_plants(ob, short); |
| 79 | return ::sell_obj(ob,short); |
| 80 | } |
| 81 | |
| 82 | /* |
| 83 | void reset() |
| 84 | { |
| 85 | ::reset(); |
| 86 | // Daten sind nicht sooo wichtig, als das bei jeder Aenderung |
| 87 | // gesavet werden muesste. Daher nun im reset speichern. |
| 88 | if (need_save) { |
| 89 | // basisvalue/PLANTCOUNT: Durchschnittswert eines einzelnen Krauts |
| 90 | // sum + PLANTCOUNT: Gesamtzahl verkaufter plus Zahl existierender |
| 91 | // Kraeuter |
| 92 | // Wenn also der Wert all dieser Kraeuter > 10k ist, wird jeder |
| 93 | // Einzelzaehler auf 90% gestutzt, damit die Werte nicht ins Uferlose |
| 94 | // steigen. |
| 95 | if (((sum+PLANTCOUNT)*basisvalue/PLANTCOUNT)>maxvalue) { |
| 96 | int i, newsum; |
| 97 | for (i=sizeof(count)-1; i>=0; i--) { |
| 98 | count[i] = count[i]*9/10; |
| 99 | newsum+=count[i]; |
| 100 | } |
| 101 | sum=newsum; |
| 102 | } |
| 103 | need_save=0; |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | // Aktualisiert den Datenbestand beim Kaufen oder Verkaufen eines Objekts |
| 108 | void UpdateCounter(object ob, int num) |
| 109 | { |
| 110 | int id=ob->QueryPlantId(); |
| 111 | if (id>0 && is_plant(ob)) { |
| 112 | // Kauf oder Verkauf von Kraeutern, veraendert den Wert der |
| 113 | // Kraeuter |
| 114 | // Zaehler in der Liste hochzaehlen |
| 115 | count[id]+=num; |
| 116 | if (count[id]<0) count[id]=0; // darf aber ansich nich passieren |
| 117 | // Gesamtsumme aktualisieren |
| 118 | sum+=num; |
| 119 | need_save=1; |
| 120 | } |
| 121 | ::UpdateCounter(ob, num); |
| 122 | } |
| 123 | |
| 124 | // Die Preise die hier im Labor fuer Kraeuter gezahlt und verlangt |
| 125 | // werden, sind nicht fix sondern haengen von Angebot und Nachfrage ab. |
| 126 | // Hier weiss man ueber den wahren Wert der einzelnen Kraeuter bescheid. |
| 127 | static int realValue(object ob, object player) |
| 128 | { |
| 129 | // Preise fuer normale Gueter ganz normal... |
| 130 | if (!is_plant(ob)) |
| 131 | return ob->QueryProp(P_VALUE); |
| 132 | |
| 133 | // jede Kraeuterkategorie bekommt den gleichen Wert zugewiesen. |
| 134 | // val entspricht dem aktuellen "Durchschnittswert" eines Krautes |
| 135 | int val=(sum+PLANTCOUNT)*basisvalue/PLANTCOUNT; |
| 136 | |
| 137 | // aber dieser Wert verteilt sich auf unterschiedlich viele Kraeuter |
| 138 | // (AN: Dieser Kommentar erschliesst sich mir nicht.) |
| 139 | int id=ob->QueryPlantId(); |
| 140 | if (id<=0) return 0; // illegal geclont -> wertlos |
| 141 | // ggf. die Zaehlerliste um die fehlenden Eintraege erweitern. |
| 142 | if ((id-1)>sizeof(count)) |
| 143 | count=count+allocate(id-1-sizeof(count)); |
| 144 | |
| 145 | // "mittleren Wert" des abgefragten Krautes errechnen (Division durch |
| 146 | // dessen umgesetzte Anzahl) |
| 147 | val=val/(count[id]+1); |
| 148 | |
| 149 | // Wert runden auf naechstniedrigeren glatt durch 10 teilbaren Wert. |
| 150 | return val-val%10; |
| 151 | } |
| 152 | |
| 153 | // gibt den Preis zurück, der zum Ankauf des Objektes verwendet werden soll |
| 154 | static varargs int QueryValue(object ob, int value, object player) |
| 155 | { |
| 156 | return ::QueryValue(ob, realValue(ob, player), player); |
| 157 | } |
| 158 | |
| 159 | // gibt den Preis an, zu dem das Objekt verkauft werden soll. |
| 160 | static varargs int QueryBuyValue(mixed ob, object player) |
| 161 | { |
| 162 | if (objectp(ob)) |
| 163 | return (realValue(ob, player)*QueryBuyFact(player) + 50)/100; |
| 164 | // fixed Objekte... |
| 165 | return ::QueryBuyValue(ob, player); |
| 166 | } |
| 167 | */ |