blob: a899e9fc0ef62913080d8b933eaba7d3f8afa260 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// obj/seercard.c -- bargeldloser Zahlungsverkehr auf Guthabenbasis
4//
5
6#pragma strict_types
7
8inherit "/std/thing";
9
10#include <defines.h>
11#include <properties.h>
12#include <language.h>
13#include <unit.h>
14#include <moving.h>
15#include <wizlevels.h>
16#include <money.h>
17
18#define KONTO "seercard_kontostand"
19#define BESITZER_GUELTIG \
20 (environment() && query_once_interactive(environment()) && \
21 getuid(environment()) == owner)
22
23// zum debuggen und extra public
24public string debugmode;
25public string __set_debug(string recv) {return debugmode=recv;}
26#include <living/comm.h>
27#define ZDEBUG(x) if (stringp(debugmode) && find_player(debugmode)) \
28 find_player(debugmode)->ReceiveMsg(x,MT_DEBUG,0,object_name()+": ",ME)
29//#define ZDEBUG(x)
30
31private string owner;
32
33static int _query_amount()
34{
35 int res;
36
37 // Wenn die Karte im Inv des Besitzers ist, Kontostand liefern
38 if ( BESITZER_GUELTIG && IS_SEER(environment()) ){
39 res = (int) environment()->Query(KONTO);
40
41 // ... allerdings nur, wenn er gueltig ist ;-)
42 if ( !intp(res) || res < 0 || res > 100000 )
43 return environment()->Set( KONTO, 0 ), 0;
44 else
45 return res;
46 }
47
48 // Fuer Fremde ist die Karte wertlos (bis auf ihren Materialwert)
49 return 0;
50}
51
52static string _feld()
53{
54 if ( !BESITZER_GUELTIG )
55 return break_string( "Das Feld schimmert aus jeder Richtung anders - "
56 "aber mehr kannst Du nicht erkennen.", 78 );
57
58 return "Du kannst in dem Schimmern ein paar Ziffern erkennen.\n";
59}
60
61
62static string _bild()
63{
64 if ( this_player() && getuid(this_player()) == owner )
65 return break_string( "Du findest, dass das Bild ganz schlecht "
66 "getroffen ist. Dass man selber aber auch immer "
67 "so unvorteilhaft abgebildet wird!", 78 );
68
69 return break_string( "Du findest, dass " + capitalize(owner) + " sehr gut "
70 "getroffen ist. Anscheinend wirst nur Du immer so "
71 "unvorteilhaft abgebildet.", 78 );
72}
73
74// Ueber das Argument <silent> kann nun gesteuert werden, ob man die
75// zusaetzliche Meldung ausgeben will oder nicht. Dies ist jetzt nur beim
76// Untersuchen der Karte der Fall, der Befehl "guthaben" gibt wie frueher
77// nur das Guthaben aus.
78private string _guthaben(int silent)
79{
80 int i;
81
82 if ( !BESITZER_GUELTIG )
83 return "Du kannst im Schimmern nichts erkennen.\n";
84
85 if ( !(i = _query_amount()) )
86 return "Welches Guthaben? :-)\n";
87
88 string msg =
89 "Dein Guthaben betraegt " + ((i > 1) ? to_string(i) : "eine") +
90 " Muenze" + ((i > 1) ? "n" : "") + ".\n";
91 if ( !silent )
92 msg +=
93 "Du erinnerst Dich an die Worte des Schalterbeamten, dass Deine "
94 "Seer-Card (TM) immer erst dann belastet wird, wenn Du Dein Bargeld "
95 "komplett verpulvert hast.";
96 return break_string(msg, 78, 0, BS_LEAVE_MY_LFS);
97}
98
99// Wrapper fuer das Detail "guthaben", um das neue Argument angeben zu
100// koennen
101static string _guthaben_det(string key) {
102 return _guthaben(0);
103}
104
105protected void create()
106{
107 if ( !clonep(ME) ){
108 set_next_reset(-1);
109 return;
110 }
111
112 ::create();
113
114 SetProp( P_LOG_FILE, "report/tiamak.rep" );
115 SetProp( P_NAME, "Geldkarte" );
116 SetProp( P_INFO,
117 break_string( "So sehr Du Dich auch anstrengst, Du kommst "
118 "einfach nicht hinter das Geheimnis dieser "
119 "Karte. Du weisst nur eines mit Sicherheit: "
120 "es muss etwas mit Magie zu tun haben.", 78 ) );
121 SetProp( P_GENDER, FEMALE );
122 SetProp( P_MATERIAL, ([ MAT_PEAR_WOOD: 80, MAT_MISC_MAGIC: 20 ]) );
123 SetProp( P_WEIGHT, 50 );
124 SetProp( P_VALUE, 1000 );
125 SetProp( P_NOBUY, 1 );
126
127 AddSounds( SENSE_DEFAULT,
128 break_string( "Du kannst nichts hoeren. Es sind anscheinend "
129 "auch keine losen Teile vorhanden.", 78 ) );
130
131 AddSmells( SENSE_DEFAULT, "Auch bargeldlose Zahlungsmittel stinken "
132 "nicht. ;-)\n" );
133
134 AddDetail( "sicherheit", "So etwas bietet diese Karte nicht!\n" );
135 AddDetail( "geheimnis", "Es lautet \"guthaben\". Aber verrate es "
136 "nicht weiter!\nAngeblich kannst Du das Guthaben sogar direkt "
137 "wieder abheben.\n" );
138 AddDetail( "magie", "Wenn man sie so einfach untersuchen koennte, "
139 "waere sie nicht halb so\ngeheimnisvoll.\n" );
140 AddDetail( "rechteck",
141 break_string( "An dieser Karte ist alles rechteckig: das Bild, "
142 "das merkwuerdige Feld und die Karte selber.",
143 78) );
144 AddDetail( ({ "holz", "birnbaumholz" }), "Es handelt sich um das "
145 "mindestens genauso seltene wie magische Birnbaumholz.\n" );
146 AddDetail( ({ "schriftzug", "schrift" }), "Nur wo \"Seer-Card\" drauf "
147 "steht, ist auch wirklich eine Seer-Card drin.\n" );
148 AddDetail( ({ "buchstabe", "buchstaben" }), "Sie bilden den "
149 "unvermeidlichen Schriftzug \"Seer-Card (TM)\".\n" );
150 AddDetail( "drittel", "Na unten halt.\n" );
151 AddDetail( ({ "seite", "seiten" }), "Eine von beiden.\n" );
152 AddDetail( ({ "rechte seite", "rechts" }), "Das ist die eine.\n" );
153 AddDetail( ({ "linke seite", "links" }), "Das ist die andere.\n" );
154 AddDetail( "rueckseite", "Die Rueckseite ist total leer und "
155 "langweilig.\n" );
156 AddDetail( ({ "zahl", "zahlen", "ziffern", "ziffer" }), "Vielleicht sollen "
157 "sie Dein Guthaben darstellen?\n" );
158 AddDetail( ({ "feld", "schimmern", "richtung" }), #'_feld/*'*/ );
159 AddDetail( "bild", #'_bild/*'*/ );
160 AddDetail( "guthaben", #'_guthaben_det/*'*/ );
161 AddDetail( ({ "muenze", "muenzen" }), "Tipp mal \"guthaben\" ein.\n" );
162
163 AddCmd( "guthaben", "_kontostand" );
164 AddCmd( ({ "heb", "hebe" }), "_abheben" );
165
166 AddId( ({ SEHERKARTEID, "geldkarte", "seercard", "seer-card",
167 "karte", "card" }) );
168}
169
170
171static int _kontostand( string str )
172{
173 if ( !this_player() || environment(this_object()) != this_player() )
174 return 0;
175
176 if ( !str || str == "" ){
177 write( _guthaben(1) );
178 return 1;
179 }
180
181 return 0;
182}
183
184
185// Abfrage des Kartenbesitzers von aussen
186public string query_owner()
187{
188 return owner;
189}
190
191
192// Lokale Property-Methoden
193
194static string _query_long()
195{
196 string str;
197
198 str = "Eigentlich ist die Seer-Card ziemlich schlicht gehalten. Sie ist "
199 "als ein etwa daumendickes Rechteck aus dunklem Holz geformt. "
200 "Auf der rechten Seite ist ein Bild von " +
201 ((this_player() && getuid(this_player()) == owner) ? "Dir" :
202 capitalize(owner)) + " aufgemalt. Links "
203 "daneben befindet sich ein schmucker Schriftzug in grossen silbernen "
204 "Buchstaben. Im unteren Drittel der Karte befindet sich ein dezent "
205 "schimmerndes rechteckiges Feld.";
206
207 return break_string( str, 78, 0, BS_LEAVE_MY_LFS );
208}
209
210
211static string _query_short()
212{
213 if ( !owner || !sizeof(owner) )
214 return "Eine Geldkarte";
215
216 if ( this_player() && getuid(this_player()) == owner )
217 return "Deine Seer-Card (TM)";
218
219 return "Die Geldkarte von " + capitalize(owner);
220}
221
222
223static string _query_autoloadobj()
224{
225 // Die Karte ist nur fuer den Eigentuemer autoload - auch, wenn sie in
226 // einem Paket o.ae. steckt
227 foreach (object env: all_environment())
228 {
229 if (getuid(env) == owner)
230 return owner;
231 }
232 return 0;
233}
234
235
236static string _set_autoloadobj( string wert )
237{
238 // Darf nach Personalisierung nicht mehr geaendert werden.
239 if ( !owner && stringp(wert) )
240 {
241
242 if ( member( ({ 'x', 'z', 's' }), wert[<1] ) != -1 ){
243 AddAdjective( wert+"'" );
244 AddAdjective( wert );
245 }
246
247 if ( wert[<1] != 's' )
248 AddAdjective( wert+"s" );
249
250 return owner = wert;
251 }
252 return 0;
253}
254
255
256static string _query_keep_on_sell()
257{
258 // Der Besitzer der Karte 'behaelt' sie automatisch
259 // Teil 2 der Abfrage, falls die Karte in einem Paket o.ae. steckt
260 if ( BESITZER_GUELTIG || this_player() && getuid(this_player()) == owner )
261 return owner;
262
263 // Bei den anderen je nach Wunsch
264 return Query(P_KEEP_ON_SELL);
265}
266
267
268// Man kann aus dem Guthaben auch wieder klingende Muenzen machen.
269// Wenn es denn sein muss.
270static int _abheben( string str )
271{
272 int summe, guthaben;
273 string dummy;
274
275 if ( !this_player() || environment(this_object()) != this_player() )
276 return 0;
277
278 if ( str == "1 muenze ab" )
279 summe = 1;
280 else
281 if ( !stringp(str) ||
282 sscanf( str, "%d muenzen ab%s", summe, dummy ) != 2 ||
283 summe < 1 || dummy != "" ){
284 _notify_fail( "Wieviele Muenzen moechtest Du denn abheben?\n" );
285 return 0;
286 }
287
288 if ( (guthaben = _query_amount()) < summe ){
289 _notify_fail( "So hoch ist Dein Guthaben aber nicht!\n" );
290 return 0;
291 }
292
293 if ( (int) this_player()->AddMoney(summe) != 1 ){
294 write( "Soviel Geld koenntest Du gar nicht mehr tragen.\n" );
295 return 1;
296 }
297
298 environment()->Set( KONTO, guthaben - summe );
299
300 write( break_string( "Du schuettelst Deine Seer-Card (TM) vorsichtig "
301 "hin und her und murmelst ein paar geheime Worte.\n"
302 "Ploetzlich macht es *PLOPP* und Du haeltst Geld "
303 "in den Haenden!", 78, 0, BS_LEAVE_MY_LFS ) );
304 return 1;
305}
306
307protected void NotifyMove(object dest, object oldenv, int method)
308{
309 ::NotifyMove(dest,oldenv,method);
310
311 // Besitzer der Karte setzen, falls noch keiner existiert
312 if ( !owner && environment() &&
313 query_once_interactive(environment()) )
314 {
315 owner = getuid(environment());
316
317 if ( member( ({ 'x', 'z', 's' }), owner[<1] ) != -1 ){
318 AddAdjective( owner );
319 AddAdjective( owner+"'" );
320 }
321 if ( owner[<1] != 's' )
322 AddAdjective( owner+"s" );
323 }
324}
325
326varargs int id(string str, int lvl)
327{
328 if (str==SEHERKARTEID_AKTIV
329 && BESITZER_GUELTIG)
330 return 1;
331 return ::id(str, lvl);
332}
333
334public void MergeMoney(object geld)
335{
336 if (geld && previous_object() == geld
337 && load_name(geld) == GELD
338 && BESITZER_GUELTIG)
339 {
340 int fremdamount = geld->QueryProp(P_AMOUNT);
341 int meinamount = _query_amount();
342 ZDEBUG(sprintf("MergeMoney: meinamount: %d, fremdamount: %d\n",
343 meinamount,fremdamount));
344 if (meinamount > 0 && fremdamount < 0)
345 {
346 int amount_to_merge = min(meinamount, abs(fremdamount));
347 environment()->Set( KONTO, meinamount - amount_to_merge, F_VALUE );
348 geld->SetProp(P_AMOUNT, fremdamount + amount_to_merge);
349 }
350 ZDEBUG(sprintf("MergeMoney: Final: meinamount: %d, fremdamount: %d\n",
351 _query_amount(),geld->QueryProp(P_AMOUNT)));
352 }
353}
354
355// Fuer die Zuordnung durch das Hoerrohr etc.
356public string GetOwner()
357{
358 return "Tiamak";
359}