1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "ags/engine/ac/global_region.h"
24 #include "ags/shared/ac/common.h"
25 #include "ags/shared/ac/game_version.h"
26 #include "ags/engine/ac/game_state.h"
27 #include "ags/engine/ac/region.h"
28 #include "ags/engine/ac/room.h"
29 #include "ags/engine/ac/room_status.h"
30 #include "ags/engine/debugging/debug_log.h"
31 #include "ags/shared/game/room_struct.h"
32 #include "ags/shared/gfx/bitmap.h"
33 #include "ags/engine/script/script.h"
34 #include "ags/globals.h"
35
36 namespace AGS3 {
37
38 using namespace AGS::Shared;
39
GetRegionIDAtRoom(int xxx,int yyy)40 int GetRegionIDAtRoom(int xxx, int yyy) {
41 // if the co-ordinates are off the edge of the screen,
42 // correct them to be just within
43 // this fixes walk-off-screen problems
44 xxx = room_to_mask_coord(xxx);
45 yyy = room_to_mask_coord(yyy);
46
47 if (_G(loaded_game_file_version) >= kGameVersion_262) { // Version 2.6.2+
48 if (xxx >= _GP(thisroom).RegionMask->GetWidth())
49 xxx = _GP(thisroom).RegionMask->GetWidth() - 1;
50 if (yyy >= _GP(thisroom).RegionMask->GetHeight())
51 yyy = _GP(thisroom).RegionMask->GetHeight() - 1;
52 if (xxx < 0)
53 xxx = 0;
54 if (yyy < 0)
55 yyy = 0;
56 }
57
58 int hsthere = _GP(thisroom).RegionMask->GetPixel(xxx, yyy);
59 if (hsthere <= 0 || hsthere >= MAX_ROOM_REGIONS) return 0;
60 if (_G(croom)->region_enabled[hsthere] == 0) return 0;
61 return hsthere;
62 }
63
SetAreaLightLevel(int area,int brightness)64 void SetAreaLightLevel(int area, int brightness) {
65 if ((area < 0) || (area > MAX_ROOM_REGIONS))
66 quit("!SetAreaLightLevel: invalid region");
67 if (brightness < -100) brightness = -100;
68 if (brightness > 100) brightness = 100;
69 _GP(thisroom).Regions[area].Light = brightness;
70 // disable RGB tint for this area
71 _GP(thisroom).Regions[area].Tint = 0;
72 debug_script_log("Region %d light level set to %d", area, brightness);
73 }
74
SetRegionTint(int area,int red,int green,int blue,int amount,int luminance)75 void SetRegionTint(int area, int red, int green, int blue, int amount, int luminance) {
76 if ((area < 0) || (area > MAX_ROOM_REGIONS))
77 quit("!SetRegionTint: invalid region");
78
79 if ((red < 0) || (red > 255) || (green < 0) || (green > 255) ||
80 (blue < 0) || (blue > 255)) {
81 quit("!SetRegionTint: RGB values must be 0-255");
82 }
83
84 // originally the value was passed as 0
85 // TODO: find out which versions had this; fixup only for past versions in the future!
86 if (amount == 0)
87 amount = 100;
88
89 if ((amount < 1) || (amount > 100))
90 quit("!SetRegionTint: amount must be 1-100");
91 if ((luminance < 0) || (luminance > 100))
92 quit("!SetRegionTint: luminance must be 0-100");
93
94 debug_script_log("Region %d tint set to %d,%d,%d", area, red, green, blue);
95
96 /*red -= 100;
97 green -= 100;
98 blue -= 100;*/
99
100 _GP(thisroom).Regions[area].Tint = (red & 0xFF) |
101 ((green & 0xFF) << 8) |
102 ((blue & 0XFF) << 16) |
103 ((amount & 0xFF) << 24);
104 _GP(thisroom).Regions[area].Light = (luminance * 25) / 10;
105 }
106
DisableRegion(int hsnum)107 void DisableRegion(int hsnum) {
108 if ((hsnum < 0) || (hsnum >= MAX_ROOM_REGIONS))
109 quit("!DisableRegion: invalid region specified");
110
111 _G(croom)->region_enabled[hsnum] = 0;
112 debug_script_log("Region %d disabled", hsnum);
113 }
114
EnableRegion(int hsnum)115 void EnableRegion(int hsnum) {
116 if ((hsnum < 0) || (hsnum >= MAX_ROOM_REGIONS))
117 quit("!EnableRegion: invalid region specified");
118
119 _G(croom)->region_enabled[hsnum] = 1;
120 debug_script_log("Region %d enabled", hsnum);
121 }
122
DisableGroundLevelAreas(int alsoEffects)123 void DisableGroundLevelAreas(int alsoEffects) {
124 if ((alsoEffects < 0) || (alsoEffects > 1))
125 quit("!DisableGroundLevelAreas: invalid parameter: must be 0 or 1");
126
127 _GP(play).ground_level_areas_disabled = GLED_INTERACTION;
128
129 if (alsoEffects)
130 _GP(play).ground_level_areas_disabled |= GLED_EFFECTS;
131
132 debug_script_log("Ground-level areas disabled");
133 }
134
EnableGroundLevelAreas()135 void EnableGroundLevelAreas() {
136 _GP(play).ground_level_areas_disabled = 0;
137
138 debug_script_log("Ground-level areas re-enabled");
139 }
140
RunRegionInteraction(int regnum,int mood)141 void RunRegionInteraction(int regnum, int mood) {
142 if ((regnum < 0) || (regnum >= MAX_ROOM_REGIONS))
143 quit("!RunRegionInteraction: invalid region speicfied");
144 if ((mood < 0) || (mood > 2))
145 quit("!RunRegionInteraction: invalid event specified");
146
147 // We need a backup, because region interactions can run
148 // while another interaction (eg. hotspot) is in a Wait
149 // command, and leaving our basename would call the wrong
150 // script later on
151 const char *oldbasename = _G(evblockbasename);
152 int oldblocknum = _G(evblocknum);
153
154 _G(evblockbasename) = "region%d";
155 _G(evblocknum) = regnum;
156
157 if (_GP(thisroom).Regions[regnum].EventHandlers != nullptr) {
158 run_interaction_script(_GP(thisroom).Regions[regnum].EventHandlers.get(), mood);
159 } else {
160 run_interaction_event(&_G(croom)->intrRegion[regnum], mood);
161 }
162
163 _G(evblockbasename) = oldbasename;
164 _G(evblocknum) = oldblocknum;
165 }
166
167 } // namespace AGS3
168