MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame^] | 1 | #pragma strong_types,rtt_checks |
| 2 | |
| 3 | inherit "/std/container"; |
| 4 | |
| 5 | #define U_REQ "u_req" |
| 6 | |
| 7 | #include <properties.h> |
| 8 | #include <language.h> |
| 9 | #include <defines.h> |
| 10 | #include <moving.h> |
| 11 | #include <money.h> |
| 12 | |
| 13 | // zum debuggen und extra public |
| 14 | public string debugmode; |
| 15 | public string __set_debug(string recv) {return debugmode=recv;} |
| 16 | #include <living/comm.h> |
| 17 | #define ZDEBUG(x) if (stringp(debugmode) && find_player(debugmode)) \ |
| 18 | find_player(debugmode)->ReceiveMsg(x,MT_DEBUG,0,object_name()+": ",ME) |
| 19 | //#define ZDEBUG(x) |
| 20 | |
| 21 | int dontacceptmoney; |
| 22 | |
| 23 | protected void create() |
| 24 | { |
| 25 | ::create(); |
| 26 | SetProp(P_NAME, "Geldboerse"); |
| 27 | SetProp(P_SHORT, "Eine Geldboerse"); |
| 28 | SetProp(P_LONG, "Eine schoene aus Leder gefertigte Geldboerse.\n"); |
| 29 | SetProp(P_MATERIAL, ([MAT_LEATHER:100])); |
| 30 | SetProp(P_GENDER, FEMALE); |
| 31 | SetProp(P_VALUE, 80); |
| 32 | SetProp(P_WEIGHT, 300); |
| 33 | SetProp(P_WEIGHT_PERCENT, 50); |
| 34 | SetProp(P_MAX_WEIGHT, 250000); // 1 mio. Muenzen. |
| 35 | AddId(({"geldboerse", "boerse", BOERSEID})); |
| 36 | SetProp(P_NOINSERT_MSG, |
| 37 | "Du kannst immer nur eine Geldboerse gleichzeitig benutzen.\n"); |
| 38 | } |
| 39 | |
| 40 | static string _query_keep_on_sell() |
| 41 | { |
| 42 | if (first_inventory() && living(environment())) |
| 43 | return getuid(environment()); |
| 44 | return Query(P_KEEP_ON_SELL); |
| 45 | } |
| 46 | |
| 47 | static int _query_amount() |
| 48 | { |
| 49 | object ob = first_inventory(); |
| 50 | if (load_name(ob) == GELD) |
| 51 | return ob->QueryProp(P_AMOUNT); |
| 52 | return 0; |
| 53 | } |
| 54 | |
| 55 | void AddAmount(int am) |
| 56 | { |
| 57 | object ob = first_inventory(); |
| 58 | if (load_name(ob) == GELD) |
| 59 | ob->AddAmount(am); |
| 60 | } |
| 61 | |
| 62 | string short() |
| 63 | { |
| 64 | int i; |
| 65 | switch (i=QueryProp(P_AMOUNT)) { |
| 66 | case 0: return "Eine leere Geldboerse.\n"; |
| 67 | case 1: return "Eine Geldboerse mit einer Muenze.\n"; |
| 68 | default: return "Eine Geldboerse mit "+i+" Muenzen.\n"; |
| 69 | } |
| 70 | return 0; |
| 71 | } |
| 72 | |
| 73 | // Geld darf nur rein, wenn diese Boerse schon Geld enthaelt |
| 74 | // ODER es auch keine andere im lebenden (!) Inventar gibt, die Geld |
| 75 | // enthaelt. |
| 76 | private int accept_money() |
| 77 | { |
| 78 | // wenn wir gerade zerstoert werden, ist das hier gesetzt, dann akzeptieren |
| 79 | // wir ein Geld. Sonst wurde Geld, was gerade in prepare_destruct() |
| 80 | // rausbewegt wurde, evtl. wieder reinbewegt... |
| 81 | if (dontacceptmoney) |
| 82 | return 0; |
| 83 | // Ausserhalb von Livings geht reinstecken von Geld immer. |
| 84 | if (!living(environment())) |
| 85 | return 1; |
| 86 | // wenn in uns Geld ist, auch. |
| 87 | object geld = first_inventory(); |
| 88 | if (geld && load_name(geld) == GELD) |
| 89 | return 1; // erlaubt |
| 90 | // wir haben kein Geld... Wenn es eine mit Geld im gleichen inv gibt, |
| 91 | // nehmen wir keins. |
| 92 | object andereboerse = present(GELDBOERSE_MIT_GELD, environment()); |
| 93 | if (objectp(andereboerse)) |
| 94 | return 0; |
| 95 | |
| 96 | return 1; |
| 97 | } |
| 98 | |
| 99 | varargs int PreventInsert(object ob) |
| 100 | { |
| 101 | if (ob && load_name(ob)==GELD |
| 102 | && accept_money()) |
| 103 | { |
| 104 | return ::PreventInsert(ob); |
| 105 | } |
| 106 | return 1; // nur geld erlaubt |
| 107 | } |
| 108 | |
| 109 | public void MergeMoney(object geld) |
| 110 | { |
| 111 | if (geld && previous_object() == geld |
| 112 | && load_name(geld) == GELD |
| 113 | && accept_money()) |
| 114 | { |
| 115 | int fremdamount = geld->QueryProp(P_AMOUNT); |
| 116 | // Da wir aus einen NotifyMove (d.h. move()) gerufen werden, darf hier |
| 117 | // keinesfalls ein move() gemacht werden. |
| 118 | // Wenn in uns Geld ist, prima, einfach P_AMOUNT veraendern. |
| 119 | // Wenn nicht, muessen wir ein neues Geldobjekt clonen, falls fremdamount |
| 120 | // > 0 ist. |
| 121 | object meingeld = first_inventory(); |
| 122 | if (meingeld && load_name(meingeld) == GELD) |
| 123 | { |
| 124 | int meinamount = meingeld->QueryProp(P_AMOUNT); |
| 125 | ZDEBUG(sprintf("MergeMoney: meinamount: %d, fremdamount: %d\n", |
| 126 | meinamount,fremdamount)); |
| 127 | // wenn fremdamount positiv ist, vereinigen wir uns natuerlich, auch |
| 128 | // wenn mein Geld negativ ist. Aber max. 1 Mio. Muenzen aufnehmen. |
| 129 | if (fremdamount > 0) |
| 130 | { |
| 131 | int zubuchen = min(1000000-meinamount, fremdamount); |
| 132 | ZDEBUG(sprintf("MergeMoney: zubuchen: %d\n", zubuchen)); |
| 133 | meingeld->SetProp(P_AMOUNT, meinamount + zubuchen); |
| 134 | geld->SetProp(P_AMOUNT, fremdamount - zubuchen); |
| 135 | // environment verstaendigen ueber Inventaraenderung... Und uns. Wir |
| 136 | // machen nur die beiden, weil alle hoehren Envs nicht so wichtig |
| 137 | // sind, dass es sofort gemacht werden muss. |
| 138 | environment()->_set_last_content_change(); |
| 139 | _set_last_content_change(); |
| 140 | } |
| 141 | // ansonsten vereinigen wir uns, wenn meinamount > 0 und fremdamount < 0 |
| 142 | // ist, aber nur soviel, dass hinterher in mir nix mehr verbleibt. |
| 143 | else if (meinamount > 0 && fremdamount < 0) |
| 144 | { |
| 145 | int amount_to_merge = min(meinamount, abs(fremdamount)); |
| 146 | ZDEBUG(sprintf("MergeMoney: zubuchen: %d\n", amount_to_merge)); |
| 147 | meingeld->SetProp(P_AMOUNT, meinamount - amount_to_merge); |
| 148 | geld->SetProp(P_AMOUNT, fremdamount + amount_to_merge); |
| 149 | // environment verstaendigen ueber Inventaraenderung... Und uns. Wir |
| 150 | // machen nur die beiden, weil alle hoehren Envs nicht so wichtig |
| 151 | // sind, dass es sofort gemacht werden muss. |
| 152 | environment()->_set_last_content_change(); |
| 153 | _set_last_content_change(); |
| 154 | } |
| 155 | // in anderen Faellen vereinigen wir einfach nicht (beide negativ) |
| 156 | } |
| 157 | // Ansonsten nehmen wir nur positives Geld und nur, soweit es noch |
| 158 | // reinpasst. |
| 159 | else if (fremdamount > 0) |
| 160 | { |
| 161 | ZDEBUG(sprintf("MergeMoney: leere Boerse, fremdamount: %d\n", |
| 162 | fremdamount)); |
| 163 | meingeld = clone_object(GELD); |
| 164 | // nocheck, weil wir eigentlich <geld> bewegen wollen und schon |
| 165 | // festgestellt haben, dass diese Boerse Geld akzeptiert. Tragen kann |
| 166 | // der Spieler es auch (sogar ohne Gewichtsreduktion). Die Boerse soll |
| 167 | // max. 1Mio Muenzen aufnehmen. |
| 168 | int zubuchen = min(fremdamount,1000000); |
| 169 | ZDEBUG(sprintf("MergeMoney: zubuchen: %d\n", zubuchen)); |
| 170 | meingeld->SetProp(P_AMOUNT, zubuchen); |
| 171 | geld->SetProp(P_AMOUNT, fremdamount-zubuchen); |
| 172 | meingeld->move(this_object(), M_NOCHECK); |
| 173 | // environment verstaendigen ueber Inventaraenderung durch geld->SetProp |
| 174 | environment()->_set_last_content_change(); |
| 175 | } |
| 176 | ZDEBUG(sprintf("MergeMoney: Final: meinamount: %d, fremdamount: %d\n", |
| 177 | meingeld->QueryProp(P_AMOUNT),geld->QueryProp(P_AMOUNT))); |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | varargs int remove(int silent) |
| 182 | { |
| 183 | dontacceptmoney=1; |
| 184 | return ::remove(silent); |
| 185 | } |
| 186 | |
| 187 | varargs int id(string str, int lvl) |
| 188 | { |
| 189 | if (str==GELDBOERSE_MIT_GELD |
| 190 | && load_name(first_inventory()) == GELD) |
| 191 | return 1; |
| 192 | return ::id(str, lvl); |
| 193 | } |
| 194 | |