blob: 435400f22856b851971b806bc47b2ecf5f0ed319 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// container/light.c -- Lichtsystem fuer Container
4//
5// $Id: description.c 6986 2008-08-22 21:32:15Z Zesstra $
6
7inherit "/std/thing/light";
8
9#pragma strict_types
10#pragma save_types,rtt_checks
11#pragma range_check
12#pragma no_clone
13#pragma pedantic
14
15#define NEED_PROTOTYPES
16
17#include <container.h>
18#include <properties.h>
19
20// BTW: _query_last_content_change() sollte bloss nie auch -1 fuer
21// uninitialisiert zurueckliefern...
22private nosave int last_light_calc = -1;
23
24protected void create()
25{
26 ::create();
27 // wieviel Licht schluckt der Container _muss_ > 0 sein!
28 SetProp(P_LIGHT_TRANSPARENCY, 2);
29}
30
31protected void create_super() {set_next_reset(-1);}
32
33
34static mixed _query_light_transparency()
35{
36 if (QueryProp(P_TRANSPARENT))
37 return Query(P_LIGHT_TRANSPARENCY,F_VALUE);
38 return 999;
39}
40
41public int add_light_sources(int * sources) {
42 float light = 0.0;
43 //printf("als(%O): %O\n",this_object(),sources);
44 // Alle Lichtlevel werden als Exponent von e aufgefasst und die Summe dieser
45 // Potenzen gebildet.
46 foreach(int l : sources) {
47 if (l > 0)
48 light += exp(l);
49 else if (l < 0)
50 light -= exp(abs(l));
51 // l==0 muss ignoriert werden
52 }
53 // anschliessend wird aus dieser Summe der natuerliche Logarithmus
54 // berechnet.
55 // auf diese Weise haben hoehere Lichtlevel ueberproportional viel Einfluss
56 // auf die Helligkeit im Raum, kleine Lichtlevel fallen aber nicht komplett
57 // raus.
58 if (light > 0) {
59 light = log(light);
60 }
61 else if (light < 0) {
62 light = -log(abs(light));
63 }
64
65 //printf("als(): %O\n",light);
66 // runden und als int zurueckgeben.
67 if (light >= 0)
68 return to_int(light+0.5);
69 //else
70 return to_int(light-0.5);
71}
72
73static int _query_total_light()
74{
75 int totallight;
76
77 if ( _query_last_content_change() == last_light_calc )
78 return Query(P_TOTAL_LIGHT);
79
80 // eigenes P_LIGHT und P_TOTAL_LIGHT der enthaltenen Objekte verrechnen
81 int intlight = add_light_sources(
82 all_inventory()->QueryProp(P_TOTAL_LIGHT) + ({QueryProp(P_LIGHT)}));
83 // P_INT_LIGHT (gerundet) abspeichern
84 Set(P_INT_LIGHT, intlight, F_VALUE);
85
86 // Licht nach aussen muss Containertransparenz beruecksichtigen.
87 if (intlight > 0) {
88 totallight = intlight - QueryProp(P_LIGHT_TRANSPARENCY);
89 if (totallight < 0)
90 totallight = 0;
91 }
92 else {
93 totallight = intlight + QueryProp(P_LIGHT_TRANSPARENCY);
94 if (totallight > 0)
95 totallight = 0;
96 }
97 //printf("_query_total_light(%O): %O\n",this_object(),totallight);
98
99 last_light_calc = _query_last_content_change();
100
101 // Runden und Konversion nach int nicht vergessen...
102 if (totallight > 0)
103 return SetProp(P_TOTAL_LIGHT, to_int(totallight + 0.5));
104 //else
105 return SetProp(P_TOTAL_LIGHT, to_int(totallight - 0.5));
106}
107
108static int _query_int_light()
109{
110 int intlight, envlight;
111
112 if ( _query_last_content_change() != last_light_calc )
113 _query_total_light();
114
115 // P_INT_LIGHT des environments kann sich natuerlich aendern _ohne_ das
116 // etwas an einem container geaendert wird. Daher Auswertung jedes mal
117 // neu aktualisieren.
118 if (!environment()
119 || !(envlight=(int)environment()->QueryProp(P_INT_LIGHT)))
120 return Query(P_INT_LIGHT, F_VALUE);
121 else {
122 intlight = Query(P_INT_LIGHT, F_VALUE);
123 int transparency = QueryProp(P_LIGHT_TRANSPARENCY);
124
125 // bei einem transparentem Container kann natuerlich das Licht des
126 // environments den Container auch ausleuchten....
127 // (Anmerkung: in dem Licht von draussen ist unser Lichtanteil
128 // natuerlich auch drin, gedaempft um die Transparenz (raus und rein).
129 // Ich vernachlaessige das.)
130 if (abs(envlight) > transparency) {
131 if (envlight > 0)
132 envlight -= transparency;
133 else
134 envlight += transparency;
135 // jetzt Licht von aussen und innen verrechnen
136 intlight = add_light_sources(({intlight, envlight}));
137 }
138 // else: nur P_INT_LIGHT, Licht des Environments keine Bedeutung
139 }
140 return intlight;
141}
142
143static int _set_light(int light)
144{
145 last_light_calc=-1;
146
147 return ::_set_light(light);
148}
149