MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame^] | 1 | /*OBJ*/ |
| 2 | /* 2013-Mai-23, Arathorn |
| 3 | Umfassend ueberarbeitet; setup(), init() und ReplaceWasser() entsorgt, |
| 4 | P_WEIGHT und P_LONG dynamisch gebaut, so dass das staendige Umsetzen |
| 5 | der Properties mittels setup() nach jedem Fuellen/Leeren entfaellt. |
| 6 | */ |
| 7 | |
| 8 | /* Letzte Aenderung: 4.5.2004, Arathorn. |
| 9 | Zeile 149: cont_obj->remove() eingefuegt, damit das geclonte Objekt |
| 10 | nach dem Abfragen seines Namens wieder entfernt wird. |
| 11 | Update 6.6.2004, Arathorn. Habe um ein destruct() ergaenzt, weil das |
| 12 | trotz remove() hartnaeckig weitergebuggt hat. *fluch* |
| 13 | */ |
| 14 | |
| 15 | /* Version 1.3 by Fraggle (17.1.1995) */ |
| 16 | |
| 17 | // PreventInsert: verhindert Fuellen wie std/container |
| 18 | /* Version 1.2 by Fraggle (17.1.1995) */ |
| 19 | |
| 20 | // Flasche kann nun mittels environment(TP)->GetLiquid() |
| 21 | // etwas anderes als Wasser enthalten, sofern |
| 22 | // environment(TP)->QueryProp(P_WATER)==W_OTHER |
| 23 | // BUG: auch 1l Methan wiegt 1 Kg, aendere ich spaeter |
| 24 | |
| 25 | /* Version 1.1 by Fraggle (17.1.1995) */ |
| 26 | #pragma strong_types,rtt_checks |
| 27 | #pragma no_clone |
| 28 | |
| 29 | inherit "/std/thing"; |
| 30 | #include <language.h> |
| 31 | #include <properties.h> |
| 32 | #include <items/flasche.h> |
| 33 | #include <items/fishing/fishing.h> |
| 34 | |
| 35 | #define DEFAULT_LIQ "Wasser" |
| 36 | #define TP this_player() |
| 37 | |
| 38 | private string co_filename; |
| 39 | public string liquid_name=DEFAULT_LIQ; |
| 40 | |
| 41 | string dynamic_long(); |
| 42 | |
| 43 | protected void create() { |
| 44 | ::create(); |
| 45 | |
| 46 | AddId(({"wasserbehaelter","behaelter","\nwater_source"})); |
| 47 | SetProp(P_NAME, "Wasserbehaelter"); |
| 48 | SetProp(P_GENDER , MALE); |
| 49 | SetProp(P_ARTICLE, 1); |
| 50 | SetProp(P_SHORT, "Ein Standard-Wasserbehaelter"); |
| 51 | SetProp(P_LONG,"none"); |
| 52 | Set(P_LONG, #'dynamic_long, F_QUERY_METHOD); |
| 53 | SetProp(P_LONG_EMPTY,""); // Beschreibung fuer leeren Zustand |
| 54 | SetProp(P_LONG_FULL,""); // Beschreibung fuer gefuellten Zusand |
| 55 | SetProp(P_LIQUID,1000); // Fuellmenge = 1 Liter |
| 56 | SetProp(P_WATER,0); // Flasche ist defaultmaessig leer! |
| 57 | SetProp(P_VALUE,10); |
| 58 | |
| 59 | // P_WEIGHT auf Leergewicht der Flasche setzen, QueryMethode liefert |
| 60 | // die Summe aus Leergewicht+Fuellung zurueck (Dichte = 1). |
| 61 | SetProp(P_WEIGHT,20); |
| 62 | Set(P_WEIGHT, function int () { |
| 63 | return ( Query(P_WEIGHT,F_VALUE)+ |
| 64 | (QueryProp(P_WATER)?QueryProp(P_LIQUID):0) ); |
| 65 | }, F_QUERY_METHOD); |
| 66 | |
| 67 | AddCmd(({"fuell","fuelle"}),"cmd_fuelle"); |
| 68 | AddCmd(({"leere", "entleere"}),"cmd_leere"); |
| 69 | } |
| 70 | |
| 71 | protected void create_super() { |
| 72 | set_next_reset(-1); |
| 73 | } |
| 74 | |
| 75 | // Behaelter ist gefuellt, dann ist die Langbeschreibung entweder die |
| 76 | // P_LONG_FULL, falls angegben, oder die P_LONG + Beschreibung der Fuellung. |
| 77 | // Genauso, wenn sie leer ist. |
| 78 | string dynamic_long() { |
| 79 | string l=Query(P_LONG,F_VALUE); |
| 80 | if ( QueryProp(P_WATER) ) { |
| 81 | string lf = QueryProp(P_LONG_FULL); |
| 82 | if ( stringp(lf) && sizeof(lf) ) |
| 83 | l=lf; |
| 84 | else |
| 85 | l+=capitalize(QueryPronoun(WER))+" enthaelt "+liquid_name+".\n"; |
| 86 | // Falls die Flasche mit etwas anderem als Wasser gefuellt wird, die |
| 87 | // Langbeschreibung fuer "volle Flasche" (P_LONG_FULL) aber nur fuer |
| 88 | // Wasser ausgelegt ist, wird "Wasser" durch den Inhalt von liquid_name |
| 89 | // ersetzt. |
| 90 | if ( liquid_name != DEFAULT_LIQ ) |
| 91 | l=regreplace(l, DEFAULT_LIQ, liquid_name, 1); |
| 92 | } else { |
| 93 | string le = QueryProp(P_LONG_EMPTY); |
| 94 | if ( stringp(le) && sizeof(le) ) |
| 95 | l=le; |
| 96 | else |
| 97 | l+=capitalize(QueryPronoun(WER))+" ist leer.\n"; |
| 98 | } |
| 99 | return l; |
| 100 | } |
| 101 | |
| 102 | // Zum Ueberschreiben! PreventInsert(object ob){return 0;} z.B. |
| 103 | // macht die Flasche gasdicht. |
| 104 | // Oder man kann die Flasche verschliessbar machen. |
| 105 | int PreventInsert(object obj) |
| 106 | { |
| 107 | if(obj->id("gas")) { //default: NICHT Gasdicht! |
| 108 | write(obj->Name(WER,1)+" entweicht sofort wieder!\n"); |
| 109 | return 1; |
| 110 | } |
| 111 | return 0; |
| 112 | } |
| 113 | |
| 114 | // Transferiert den Inhalt der Flasche an <dest> |
| 115 | protected int transfer_to(object dest) |
| 116 | { |
| 117 | int water=QueryProp(P_WATER); |
| 118 | if (!water) |
| 119 | { |
| 120 | write(Name(WER,1) + " ist schon leer!\n"); |
| 121 | return 0; // War schon leer! |
| 122 | } |
| 123 | int contents=QueryProp(P_LIQUID); |
| 124 | |
| 125 | if ( water&W_OTHER ) |
| 126 | { |
| 127 | dest->PutLiquid(co_filename); |
| 128 | } |
| 129 | else |
| 130 | { |
| 131 | dest->AddWater(contents); |
| 132 | } |
| 133 | SetProp(P_WATER,0); |
| 134 | RemoveId(lower_case(liquid_name)); |
| 135 | liquid_name=DEFAULT_LIQ; |
| 136 | return contents; //gib die ml an Umgebung ab :) |
| 137 | } |
| 138 | |
| 139 | // Entleert die Flasche ins Environment der Flasche, allerdings nicht, wenn |
| 140 | // dies ein Lebewesen ist, dann wird das Environment von dem genommen. |
| 141 | // TODO: Eine Flasche in einem Paket leeren wurde dann in das paket entleeren. |
| 142 | // Das waere an sich sogar richtig... Nur: gewollt? Alternative koennen wir |
| 143 | // auch das aeusserste Environment nehmen, was nicht lebt. |
| 144 | public int empty() |
| 145 | { |
| 146 | if (environment()) |
| 147 | { |
| 148 | // Environment des Benutzers finden. |
| 149 | object env = environment(); |
| 150 | while (living(env)) |
| 151 | env=environment(env); |
| 152 | return transfer_to(env); |
| 153 | } |
| 154 | return 0; |
| 155 | } |
| 156 | |
| 157 | // Fuellt die Flasche aus <src> |
| 158 | protected int fill_bottle(object src) |
| 159 | { |
| 160 | int liquidtype = src->QueryProp(P_WATER); |
| 161 | if(liquidtype) |
| 162 | { |
| 163 | if(QueryProp(P_WATER)) { |
| 164 | write(Name(WER,1)+" ist bereits voll!\n"); |
| 165 | return 1; |
| 166 | } |
| 167 | // Wasser von Umgebung abziehen! |
| 168 | // Man kann als Magier die Funktion AddWater(int n) dazu benuetzten, |
| 169 | // beispielsweise eine Pfuetze zu leeren, ... |
| 170 | src->AddWater(-QueryProp(P_LIQUID)); |
| 171 | object cont_obj; |
| 172 | if(liquidtype&W_OTHER) |
| 173 | { |
| 174 | // Mittels GetLiquid() kann die Flasche mit was anderem als Wasser |
| 175 | // gefuellt werden. |
| 176 | co_filename=src->GetLiquid(); |
| 177 | if (co_filename) |
| 178 | { |
| 179 | cont_obj=clone_object(co_filename); |
| 180 | if(PreventInsert(cont_obj)) |
| 181 | { |
| 182 | // Hier passiert eigentlich das gleiche wie nach dem ifblock, aber |
| 183 | // auch noch Funktion beenden. |
| 184 | // TODO: Rueckgaenig machen von AddWater()? |
| 185 | // TODO: Die Meldung aus dem PreventInsert() muesste eigentlich |
| 186 | // _vorher_ noch mit einer Befuellmeldung begleitet werden. |
| 187 | cont_obj->remove(1); |
| 188 | if ( objectp(cont_obj) ) |
| 189 | cont_obj->move("/room/muellraum",M_PUT); |
| 190 | cont_obj=0; |
| 191 | return 0; |
| 192 | } |
| 193 | else |
| 194 | liquid_name=cont_obj->name(WEN); |
| 195 | // In jedem Fall wird das Objekt wieder zerstoert - es wurde nur fuer |
| 196 | // das Ermitteln des liquid_name benutzt... Weia. |
| 197 | if ( cont_obj ) cont_obj->remove(); |
| 198 | if ( cont_obj ) cont_obj->move("/room/muellraum",M_PUT); |
| 199 | } |
| 200 | } |
| 201 | SetProp(P_WATER,liquidtype); |
| 202 | AddId(lower_case(liquid_name)); |
| 203 | //wie praktisch, 1 ml == 1 g :) // Aber nur fuer Wasser, du VOGEL! :-| |
| 204 | return 1; |
| 205 | } |
| 206 | else { |
| 207 | write("Du findest hier nichts, was Du in "+name(WEN,1)+ |
| 208 | " fuellen koenntest!\n"); |
| 209 | return 0; |
| 210 | } |
| 211 | return 0; |
| 212 | } |
| 213 | |
| 214 | static int cmd_leere(string str) |
| 215 | { |
| 216 | object dest; |
| 217 | notify_fail("Was willst Du denn (wo hinein) leeren?\n"); |
| 218 | if (!str) |
| 219 | return 0; |
| 220 | |
| 221 | string strbottle,strobj; |
| 222 | // leere flasche |
| 223 | if (id(str)) |
| 224 | { |
| 225 | //NOOP |
| 226 | } |
| 227 | // leere flasche in xxx |
| 228 | else if (sscanf(str,"%s in %s",strbottle,strobj)==2) |
| 229 | { |
| 230 | if (!id(strbottle)) |
| 231 | return 0; |
| 232 | dest = present(strobj, environment(this_player())) |
| 233 | || present(strobj, this_player()); |
| 234 | if (!dest) |
| 235 | return 0; |
| 236 | } |
| 237 | else |
| 238 | return 0; |
| 239 | // Syntaxpruefung fertig. |
| 240 | |
| 241 | if(!QueryProp(P_WATER)) |
| 242 | { |
| 243 | write("Da ist kein "+liquid_name+" drin!\n"); |
| 244 | return 1; |
| 245 | } |
| 246 | |
| 247 | if (dest) |
| 248 | { |
| 249 | write(break_string("Du leerst "+name(WEN,1)+ " in " |
| 250 | + dest->name(WEN) + ".",78)); |
| 251 | say(break_string(TP->name()+" leert "+name(WEN,0) |
| 252 | + " in " + dest->name(WEN) + ".",78),TP); |
| 253 | transfer_to(dest); |
| 254 | return 1; |
| 255 | } |
| 256 | write(break_string("Du leerst "+name(WEN,1)+".",78)); |
| 257 | say(break_string(TP->name()+" leert "+name(WEN,0)+".",78),TP); |
| 258 | empty(); |
| 259 | return 1; |
| 260 | } |
| 261 | |
| 262 | public int cmd_fuelle(string str) |
| 263 | { |
| 264 | string strbottle,strobj; |
| 265 | |
| 266 | notify_fail("Was willst Du denn (womit) fuellen?\n"); |
| 267 | if(!str) |
| 268 | return 0; |
| 269 | |
| 270 | // fuelle flasche |
| 271 | if (id(str)) |
| 272 | { |
| 273 | if (fill_bottle(environment(this_player()))) |
| 274 | { |
| 275 | write(break_string("Du fuellst etwas "+liquid_name+" in " |
| 276 | +name(WEN,1)+".",78)); |
| 277 | say(break_string(TP->Name(WER)+" fuellt etwas " |
| 278 | +liquid_name+" in "+name(WEN)+".",78), TP); |
| 279 | } |
| 280 | return 1; |
| 281 | } |
| 282 | // fuelle flasche aus xxx |
| 283 | // fuelle flasche mit xxx |
| 284 | // fuelle xxx in flasche |
| 285 | // fuelle flasche in xxx |
| 286 | // fuelle xxx aus flasche |
| 287 | // fuelle xxx mit flasche |
| 288 | else if (sscanf(str,"%s in %s",strobj,strbottle)==2 |
| 289 | || sscanf(str,"%s mit %s",strbottle,strobj)==2 |
| 290 | || sscanf(str,"%s aus %s",strbottle,strobj)==2) |
| 291 | { |
| 292 | object obj; |
| 293 | // Flasche befuellen? |
| 294 | if (id(strbottle) |
| 295 | && ( obj=present(strobj, environment(this_player())) |
| 296 | || present(strobj, this_player()) ) |
| 297 | ) |
| 298 | { |
| 299 | if (fill_bottle(obj)) |
| 300 | { |
| 301 | write(break_string( |
| 302 | "Du fuellst etwas "+liquid_name+" aus " + obj->name(WEM,1) |
| 303 | + " in "+name(WEN,1)+".",78)); |
| 304 | say(break_string(TP->Name(WER)+" fuellt etwas "+liquid_name+ " aus " |
| 305 | + obj->name(WEM,1) + " in "+name(WEN)+".",78), TP); |
| 306 | } |
| 307 | return 1; |
| 308 | } |
| 309 | // anderes Gefaess befuellen? |
| 310 | else if (id(strobj) |
| 311 | && ( obj=present(strbottle, environment(this_player())) |
| 312 | || present(strbottle, this_player()) ) |
| 313 | ) |
| 314 | { |
| 315 | if (transfer_to(obj)) |
| 316 | { |
| 317 | write(break_string( |
| 318 | "Du fuellst etwas "+liquid_name+" aus " + name(WEM,1) |
| 319 | + " in "+obj->name(WEN,1)+".",78)); |
| 320 | say(break_string(TP->Name(WER)+" fuellt etwas "+liquid_name+ " aus " |
| 321 | + name(WEM,1) + " in "+obj->name(WEN)+".",78), TP); |
| 322 | } |
| 323 | return 1; |
| 324 | } |
| 325 | } |
| 326 | // Syntax passt nicht. |
| 327 | return 0; |
| 328 | } |
| 329 | |
| 330 | int IsBottle() { |
| 331 | return 1; |
| 332 | } |
| 333 | |