1 //=============================================================================
2 //
3 // Adventure Game Studio (AGS)
4 //
5 // Copyright (C) 1999-2011 Chris Jones and 2011-20xx others
6 // The full list of copyright holders can be found in the Copyright.txt
7 // file, which is part of this source code distribution.
8 //
9 // The AGS source code is provided under the Artistic License 2.0.
10 // A copy of this license can be found in the file License.txt and at
11 // http://www.opensource.org/licenses/artistic-license-2.0.php
12 //
13 //=============================================================================
14
15 #include "ac/global_room.h"
16 #include "ac/common.h"
17 #include "ac/character.h"
18 #include "ac/characterinfo.h"
19 #include "ac/draw.h"
20 #include "ac/event.h"
21 #include "ac/gamesetupstruct.h"
22 #include "ac/gamestate.h"
23 #include "ac/global_character.h"
24 #include "ac/global_game.h"
25 #include "ac/movelist.h"
26 #include "ac/properties.h"
27 #include "ac/room.h"
28 #include "ac/roomstatus.h"
29 #include "debug/debug_log.h"
30 #include "debug/debugger.h"
31 #include "script/script.h"
32 #include "util/math.h"
33
34 using namespace Common;
35
36 extern GameState play;
37 extern GameSetupStruct game;
38 extern RoomStatus *croom;
39 extern CharacterInfo*playerchar;
40 extern int displayed_room;
41 extern int in_enters_screen;
42 extern int in_leaves_screen;
43 extern int in_inv_screen, inv_screen_newroom;
44 extern MoveList *mls;
45 extern int gs_to_newroom;
46 extern roomstruct thisroom;
47
SetAmbientTint(int red,int green,int blue,int opacity,int luminance)48 void SetAmbientTint (int red, int green, int blue, int opacity, int luminance) {
49 if ((red < 0) || (green < 0) || (blue < 0) ||
50 (red > 255) || (green > 255) || (blue > 255) ||
51 (opacity < 0) || (opacity > 100) ||
52 (luminance < 0) || (luminance > 100))
53 quit("!SetTint: invalid parameter. R,G,B must be 0-255, opacity & luminance 0-100");
54
55 debug_script_log("Set ambient tint RGB(%d,%d,%d) %d%%", red, green, blue, opacity);
56
57 play.rtint_enabled = opacity > 0;
58 play.rtint_red = red;
59 play.rtint_green = green;
60 play.rtint_blue = blue;
61 play.rtint_level = opacity;
62 play.rtint_light = (luminance * 25) / 10;
63 }
64
SetAmbientLightLevel(int light_level)65 void SetAmbientLightLevel(int light_level)
66 {
67 light_level = Math::Clamp(-100, 100, light_level);
68
69 play.rtint_enabled = light_level != 0;
70 play.rtint_level = 0;
71 play.rtint_light = light_level;
72 }
73
74 extern ScriptPosition last_in_dialog_request_script_pos;
NewRoom(int nrnum)75 void NewRoom(int nrnum) {
76 if (nrnum < 0)
77 quitprintf("!NewRoom: room change requested to invalid room number %d.", nrnum);
78
79 if (displayed_room < 0) {
80 // called from game_start; change the room where the game will start
81 playerchar->room = nrnum;
82 return;
83 }
84
85
86 debug_script_log("Room change requested to room %d", nrnum);
87 EndSkippingUntilCharStops();
88
89 can_run_delayed_command();
90
91 if (play.stop_dialog_at_end != DIALOG_NONE) {
92 if (play.stop_dialog_at_end == DIALOG_RUNNING)
93 play.stop_dialog_at_end = DIALOG_NEWROOM + nrnum;
94 else {
95 quitprintf("!NewRoom: two NewRoom/RunDialog/StopDialog requests within dialog; last was called in \"%s\", line %d",
96 last_in_dialog_request_script_pos.Section.GetCStr(), last_in_dialog_request_script_pos.Line);
97 }
98 return;
99 }
100
101 get_script_position(last_in_dialog_request_script_pos);
102
103 if (in_leaves_screen >= 0) {
104 // NewRoom called from the Player Leaves Screen event -- just
105 // change which room it will go to
106 in_leaves_screen = nrnum;
107 }
108 else if (in_enters_screen) {
109 setevent(EV_NEWROOM,nrnum);
110 return;
111 }
112 else if (in_inv_screen) {
113 inv_screen_newroom = nrnum;
114 return;
115 }
116 else if ((inside_script==0) & (in_graph_script==0)) {
117 new_room(nrnum,playerchar);
118 return;
119 }
120 else if (inside_script) {
121 curscript->queue_action(ePSANewRoom, nrnum, "NewRoom");
122 // we might be within a MoveCharacterBlocking -- the room
123 // change should abort it
124 if ((playerchar->walking > 0) && (playerchar->walking < TURNING_AROUND)) {
125 // nasty hack - make sure it doesn't move the character
126 // to a walkable area
127 mls[playerchar->walking].direct = 1;
128 StopMoving(game.playercharacter);
129 }
130 }
131 else if (in_graph_script)
132 gs_to_newroom = nrnum;
133 }
134
135
NewRoomEx(int nrnum,int newx,int newy)136 void NewRoomEx(int nrnum,int newx,int newy) {
137 Character_ChangeRoom(playerchar, nrnum, newx, newy);
138 }
139
NewRoomNPC(int charid,int nrnum,int newx,int newy)140 void NewRoomNPC(int charid, int nrnum, int newx, int newy) {
141 if (!is_valid_character(charid))
142 quit("!NewRoomNPC: invalid character");
143 if (charid == game.playercharacter)
144 quit("!NewRoomNPC: use NewRoomEx with the player character");
145
146 Character_ChangeRoom(&game.chars[charid], nrnum, newx, newy);
147 }
148
ResetRoom(int nrnum)149 void ResetRoom(int nrnum) {
150 if (nrnum == displayed_room)
151 quit("!ResetRoom: cannot reset current room");
152 if ((nrnum<0) | (nrnum>=MAX_ROOMS))
153 quit("!ResetRoom: invalid room number");
154
155 if (isRoomStatusValid(nrnum))
156 {
157 RoomStatus* roomstat = getRoomStatus(nrnum);
158 roomstat->FreeScriptData();
159 roomstat->FreeProperties();
160 roomstat->beenhere = 0;
161 }
162
163 debug_script_log("Room %d reset to original state", nrnum);
164 }
165
HasPlayerBeenInRoom(int roomnum)166 int HasPlayerBeenInRoom(int roomnum) {
167 if ((roomnum < 0) || (roomnum >= MAX_ROOMS))
168 return 0;
169 if (isRoomStatusValid(roomnum))
170 return getRoomStatus(roomnum)->beenhere;
171 else
172 return 0;
173 }
174
CallRoomScript(int value)175 void CallRoomScript (int value) {
176 can_run_delayed_command();
177
178 if (!inside_script)
179 quit("!CallRoomScript: not inside a script???");
180
181 play.roomscript_finished = 0;
182 RuntimeScriptValue rval_null;
183 curscript->run_another("on_call", kScInstRoom, 1, RuntimeScriptValue().SetInt32(value), rval_null);
184 }
185
HasBeenToRoom(int roomnum)186 int HasBeenToRoom (int roomnum) {
187 if ((roomnum < 0) || (roomnum >= MAX_ROOMS))
188 quit("!HasBeenToRoom: invalid room number specified");
189
190 if (isRoomStatusValid(roomnum))
191 return getRoomStatus(roomnum)->beenhere;
192 else
193 return 0;
194 }
195
GetRoomPropertyText(const char * property,char * bufer)196 void GetRoomPropertyText (const char *property, char *bufer)
197 {
198 get_text_property(thisroom.roomProps, croom->roomProps, property, bufer);
199 }
200
SetBackgroundFrame(int frnum)201 void SetBackgroundFrame(int frnum) {
202 if ((frnum<-1) | (frnum>=thisroom.num_bscenes))
203 quit("!SetBackgrondFrame: invalid frame number specified");
204 if (frnum<0) {
205 play.bg_frame_locked=0;
206 return;
207 }
208
209 play.bg_frame_locked = 1;
210
211 if (frnum == play.bg_frame)
212 {
213 // already on this frame, do nothing
214 return;
215 }
216
217 play.bg_frame = frnum;
218 on_background_frame_change ();
219 }
220
GetBackgroundFrame()221 int GetBackgroundFrame() {
222 return play.bg_frame;
223 }
224