1 /*
2  * Copyright 2011-2013 Arx Libertatis Team (see the AUTHORS file)
3  *
4  * This file is part of Arx Libertatis.
5  *
6  * Arx Libertatis is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Arx Libertatis is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Arx Libertatis.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 /* Based on:
20 ===========================================================================
21 ARX FATALIS GPL Source Code
22 Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company.
23 
24 This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code').
25 
26 Arx Fatalis Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
27 License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
28 
29 Arx Fatalis Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
30 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
31 
32 You should have received a copy of the GNU General Public License along with Arx Fatalis Source Code.  If not, see
33 <http://www.gnu.org/licenses/>.
34 
35 In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these
36 additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx
37 Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below.
38 
39 If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o
40 ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
41 ===========================================================================
42 */
43 // Copyright (c) 1999-2000 ARKANE Studios SA. All rights reserved
44 
45 #include "gui/Interface.h"
46 
47 #include <stddef.h>
48 #include <cmath>
49 #include <iomanip>
50 #include <sstream>
51 #include <cstdio>
52 #include <cstdlib>
53 #include <cstring>
54 #include <algorithm>
55 #include <set>
56 #include <utility>
57 #include <vector>
58 
59 #include <boost/algorithm/string/predicate.hpp>
60 
61 #include "animation/Animation.h"
62 
63 #include "core/Application.h"
64 #include "core/ArxGame.h"
65 #include "core/Config.h"
66 #include "core/GameTime.h"
67 #include "core/Localisation.h"
68 #include "core/Core.h"
69 
70 #include "game/Damage.h"
71 #include "game/EntityManager.h"
72 #include "game/Equipment.h"
73 #include "game/Inventory.h"
74 #include "game/Item.h"
75 #include "game/Levels.h"
76 #include "game/NPC.h"
77 #include "game/Player.h"
78 
79 #include "graphics/BaseGraphicsTypes.h"
80 #include "graphics/Color.h"
81 #include "graphics/GraphicsTypes.h"
82 #include "graphics/Draw.h"
83 #include "graphics/Math.h"
84 #include "graphics/Renderer.h"
85 #include "graphics/Vertex.h"
86 #include "graphics/data/Mesh.h"
87 #include "graphics/data/TextureContainer.h"
88 #include "graphics/effects/DrawEffects.h"
89 #include "graphics/particle/ParticleEffects.h"
90 #include "graphics/texture/TextureStage.h"
91 #include "graphics/texture/Texture.h"
92 
93 #include "gui/Menu.h"
94 #include "gui/Speech.h"
95 #include "gui/MiniMap.h"
96 #include "gui/TextManager.h"
97 #include "gui/Text.h"
98 
99 #include "input/Input.h"
100 #include "input/Keyboard.h"
101 
102 #include "io/resource/ResourcePath.h"
103 
104 #include "math/Angle.h"
105 #include "math/Random.h"
106 #include "math/Rectangle.h"
107 #include "math/Vector2.h"
108 #include "math/Vector3.h"
109 
110 #include "physics/Box.h"
111 #include "physics/Collisions.h"
112 
113 #include "scene/LinkedObject.h"
114 #include "scene/GameSound.h"
115 #include "scene/Interactive.h"
116 #include "scene/Light.h"
117 
118 #include "script/Script.h"
119 
120 #include "window/RenderWindow.h"
121 
122 extern float MagicSightFader;
123 extern float Original_framedelay;
124 extern EERIE_3DOBJ *arrowobj;
125 extern void InitTileLights();
126 
127 long Manage3DCursor(long flags); // flags & 1 == simulation
128 long IN_BOOK_DRAW=0;
129 extern float INVISIBILITY_OVERRIDE;
130 //-----------------------------------------------------------------------------
131 struct ARX_INTERFACE_HALO_STRUCT
132 {
133 	Entity  * io;
134 	TextureContainer * tc;
135 	TextureContainer * tc2;
136 	float POSX;
137 	float POSY;
138 	float fRatioX;
139 	float fRatioY;
140 };
141 //-----------------------------------------------------------------------------
142 #define GL_DECAL_ICONS		0
143 #define BOOKMARKS_POS_X		216.f
144 #define BOOKMARKS_POS_Y		60.f
145 #define PAGE_CHAR_SIZE		4096
146 
147 //-----------------------------------------------------------------------------
148 //-----------------------------------------------------------------------------
149 extern TextureContainer * iconequip[];
150 extern TextureContainer * Movable;
151 extern TextureContainer * ChangeLevel;
152 extern TextureContainer * inventory_font;
153 extern TextureContainer * scursor[];
154 extern TextureContainer * pTCCrossHair;
155 extern TextureContainer * mecanism_tc;
156 extern TextureContainer * arrow_left_tc;
157 extern TexturedVertex LATERDRAWHALO[];
158 extern Entity * CURRENT_TORCH;
159 extern Notification speech[];
160 extern std::string WILLADDSPEECH;
161 extern float PLAYER_ROTATION;
162 extern float SLID_VALUE;
163 
164 extern long BOOKBUTTON;
165 extern long LASTBOOKBUTTON;
166 extern long FORCE_NO_HIDE;
167 static long lSLID_VALUE = 0;
168 
169 extern long CHANGE_LEVEL_ICON;
170 extern long BLOCK_PLAYER_CONTROLS;
171 extern long DeadTime;
172 extern long HALOCUR;
173 extern long ALLOW_CHEATS;
174 extern long LOOKING_FOR_SPELL_TARGET;
175 extern long WILLRETURNTOFREELOOK;
176 extern float BOW_FOCAL;
177 extern Vec2s DANAEMouse;
178 extern short sActiveInventory;
179 extern unsigned long WILLADDSPEECHTIME;
180 extern unsigned long LOOKING_FOR_SPELL_TARGET_TIME;
181 
182 extern float ARXTimeMenu;
183 extern float ARXOldTimeMenu;
184 extern float ARXDiffTimeMenu;
185 
186 extern bool bGToggleCombatModeWithKey;
187 extern unsigned char ucFlick;
188 
189 extern TextManager *pTextManageFlyingOver;
190 
191 bool IsPlayerStriking();
192 
193 extern long SHOW_INGAME_MINIMAP;
194 
195 //-----------------------------------------------------------------------------
196 TextureContainer *	BasicInventorySkin=NULL;
197 TextureContainer *	ThrowObject=NULL;
198 ARX_INTERFACE_HALO_STRUCT * aiHalo=NULL;
199 E_ARX_STATE_MOUSE	eMouseState;
200 Vec2s bookclick;
201 Vec2s MemoMouse;
202 
203 INVENTORY_DATA *	TSecondaryInventory;
204 Entity * FlyingOverIO=NULL;
205 Entity *	STARTED_ACTION_ON_IO=NULL;
206 INTERFACE_TC		ITC;
207 
208 static gui::Note openNote;
209 static gui::Note questBook;
210 
211 bool				bBookHalo = false;
212 bool				bGoldHalo = false;
213 bool				bHitFlash = false;
214 bool				bInventoryClosing = false;
215 bool				bInventorySwitch = false;
216 bool				bIsAiming = false;
217 float				fHitFlash = 0;
218 unsigned long		ulHitFlash = 0;
219 unsigned long		ulBookHaloTime = 0;
220 unsigned long		ulGoldHaloTime = 0;
221 float				InventoryX=-60.f;
222 float				InventoryDir=0; // 0 stable, 1 to right, -1 to left
223 
224 float				CINEMA_DECAL=0.f;
225 float				SLID_START=0.f; // Charging Weapon
226 float				BOOKDECX=0.f;
227 float				BOOKDECY=0.f;
228 float				PROGRESS_BAR_TOTAL=0;
229 float				PROGRESS_BAR_COUNT=0;
230 float				OLD_PROGRESS_BAR_COUNT=0;
231 
232 bool				PLAYER_MOUSELOOK_ON = false;
233 bool				TRUE_PLAYER_MOUSELOOK_ON = false;
234 bool				LAST_PLAYER_MOUSELOOK_ON = false;
235 static bool MEMO_PLAYER_MOUSELOOK_ON = false;
236 
237 long				COMBINEGOLD=0;
238 ARX_INTERFACE_BOOK_MODE Book_Mode = BOOKMODE_STATS;
239 long				Book_MapPage=1;
240 long				Book_SpellPage=1;
241 long				CINEMASCOPE=0;
242 float				g_TimeStartCinemascope = 0;
243 long				CINEMA_INC=0;
244 long				SMOOTHSLID=0;
245 long				currpos=50;
246 long				DRAGGING = 0;
247 long				INVERTMOUSE=0;
248 long				PLAYER_INTERFACE_HIDE_COUNT=0;
249 long				MAGICMODE=-1;
250 long				SpecialCursor=0;
251 long				FLYING_OVER		= 0;
252 long				OLD_FLYING_OVER	= 0;
253 long				LastRune=-1;
254 long				BOOKZOOM=0;
255 Anglef			ePlayerAngle;
256 long				CURCURTIME=0;
257 long				CURCURDELAY=70;
258 long				CURCURPOS=0;
259 static long INTERFACE_HALO_NB = 0;
260 static long INTERFACE_HALO_MAX_NB = 0;
261 static long PRECAST_NUM = 0;
262 long				LastMouseClick=0;
263 
264 //used to redist points - attributes and skill
265 static long lCursorRedistValue = 0;
266 
267 unsigned long		COMBAT_MODE_ON_START_TIME = 0;
268 static long SPECIAL_DRAW_WEAPON = 0;
269 bool bGCroucheToggle=false;
270 
271 int iHighLight=0;
272 float fHighLightAng=0.f;
273 
INTERFACE_RATIO(float a)274 float INTERFACE_RATIO(float a)
275 {
276 	return a;
277 }
INTERFACE_RATIO_LONG(const long a)278 float INTERFACE_RATIO_LONG(const long a)
279 {
280 	return INTERFACE_RATIO(static_cast<float>(a));
281 }
INTERFACE_RATIO_DWORD(const u32 a)282 float INTERFACE_RATIO_DWORD(const u32 a)
283 {
284 	return INTERFACE_RATIO(static_cast<float>(a));
285 }
286 
287 
SHORT_INTERFACE_RATIO(const float _a)288 short SHORT_INTERFACE_RATIO(const float _a) {
289 	float fRes = INTERFACE_RATIO(_a);
290 	return checked_range_cast<short>(fRes);
291 }
292 
293 
294 bool bInverseInventory = false;
295 bool lOldTruePlayerMouseLook = TRUE_PLAYER_MOUSELOOK_ON;
296 bool bForceEscapeFreeLook = false;
297 bool bRenderInCursorMode = true;
298 
299 long lChangeWeapon=0;
300 Entity *pIOChangeWeapon=NULL;
301 
302 static long lTimeToDrawMecanismCursor=0;
303 static long lNbToDrawMecanismCursor=0;
304 static long lOldInterface;
305 
306 
307 
308 namespace gui {
309 
310 namespace {
311 
312 /*!
313  * Manage forward and backward buttons on notes and the quest book.
314  * @return true if the note was clicked
315  */
manageNoteActions(Note & note)316 bool manageNoteActions(Note & note) {
317 
318 	if(note.prevPageButton().contains(Vec2f(DANAEMouse))) {
319 		SpecialCursor = CURSOR_INTERACTION_ON;
320 		if(!(EERIEMouseButton & 1) && (LastMouseClick & 1)) {
321 			ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9f + 0.2f * rnd());
322 			arx_assert(note.page() >= 2);
323 			note.setPage(note.page() - 2);
324 		}
325 
326 	} else if(note.nextPageButton().contains(Vec2f(DANAEMouse))) {
327 		SpecialCursor = CURSOR_INTERACTION_ON;
328 		if(!(EERIEMouseButton & 1) && (LastMouseClick & 1)) {
329 			ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9f + 0.2f * rnd());
330 			note.setPage(note.page() + 2);
331 		}
332 
333 	} else if(note.area().contains(Vec2f(DANAEMouse))) {
334 		if(((EERIEMouseButton & 1) && !(LastMouseClick & 1) && TRUE_PLAYER_MOUSELOOK_ON)
335 		   || ((EERIEMouseButton & 2) && !(LastMouseClick & 2))) {
336 			EERIEMouseButton &= ~2;
337 			return true;
338 		}
339 	}
340 
341 	return false;
342 }
343 
344 
345 //! Update and render the quest book.
manageQuestBook()346 void manageQuestBook() {
347 
348 	// Cache the questbook data
349 	if(questBook.text().empty() && !PlayerQuest.empty()) {
350 		std::string text;
351 		for(size_t i = 0; i < PlayerQuest.size(); ++i) {
352 			std::string quest = getLocalised(PlayerQuest[i].ident);
353 			if(!quest.empty()) {
354 				text += quest;
355 				text += "\n\n";
356 			}
357 		}
358 		questBook.setData(Note::QuestBook, text);
359 		questBook.setPage(questBook.pageCount() - 1);
360 	}
361 
362 	manageNoteActions(questBook);
363 
364 	questBook.render();
365 }
366 
367 } // anonymous namespace
368 
updateQuestBook()369 void updateQuestBook() {
370 	// Clear the quest book cache - it will be re-created when needed
371 	questBook.clear();
372 }
373 
374 } // namespace gui
375 
376 //-----------------------------------------------------------------------------
ARX_CAST_TO_INT_THEN_FLOAT(float _f)377 float ARX_CAST_TO_INT_THEN_FLOAT( float _f )
378 {
379 	return ( ( _f >= 0 ) ? floor( _f ) : ceil( _f ) );
380 }
381 
382 
383 //-----------------------------------------------------------------------------
MouseInBookRect(const float x,const float y,const float cx,const float cy)384 bool MouseInBookRect(const float x, const float y, const float cx, const float cy)
385 {
386 	return ((DANAEMouse.x>=(x+BOOKDECX)*Xratio)
387 		&& (DANAEMouse.x<=(cx+BOOKDECX)*Xratio)
388 		&& (DANAEMouse.y>=(y+BOOKDECY)*Yratio)
389 	        && (DANAEMouse.y <= (cy + BOOKDECY) * Yratio));
390 }
391 
392 //-----------------------------------------------------------------------------
MouseInCam(EERIE_CAMERA * cam)393 bool MouseInCam(EERIE_CAMERA * cam)
394 {
395 	return ((DANAEMouse.x>cam->clip.left) && (DANAEMouse.x<cam->clip.right) &&
396 		(DANAEMouse.x>cam->clip.top) && (DANAEMouse.y<cam->clip.bottom));
397 }
398 
399 //-----------------------------------------------------------------------------
MouseInRect(const float x0,const float y0,const float x1=32,const float y1=32)400 bool MouseInRect(const float x0, const float y0, const float x1=32, const float y1=32)
401 {
402 	return (	(DANAEMouse.x>=x0)
403 		&&	(DANAEMouse.x<=x1)
404 		&&	(DANAEMouse.y>=y0)
405 		&&	(DANAEMouse.y<=y1) );
406 }
407 
408 //-----------------------------------------------------------------------------
ARX_INTERFACE_MouseInBook()409 bool ARX_INTERFACE_MouseInBook()
410 {
411 	if ((player.Interface & INTER_MAP ) &&  (!(player.Interface & INTER_COMBATMODE)))
412 		return (MouseInBookRect(99,65,599,372));
413 
414 	else return false;
415 }
416 
ARX_INTERFACE_DrawItem(TextureContainer * tc,float x,float y,float z=0.001f,Color col=Color::white)417 static void ARX_INTERFACE_DrawItem(TextureContainer * tc, float x, float y, float z = 0.001f, Color col = Color::white) {
418 	if(tc) {
419 		EERIEDrawBitmap(x, y, INTERFACE_RATIO_DWORD(tc->m_dwWidth), INTERFACE_RATIO_DWORD(tc->m_dwHeight), z, tc, col);
420 	}
421 }
422 
ARX_INTERFACE_DrawNumber(const float x,const float y,const long num,const int _iNb,const Color color)423 static void ARX_INTERFACE_DrawNumber(const float x, const float y, const long num, const int _iNb, const Color color) {
424 
425 	ColorBGRA col = color.toBGRA();
426 
427 	TexturedVertex v[4];
428 	v[0] = TexturedVertex(Vec3f::ZERO, 1.f, 1, 1, Vec2f::ZERO);
429 	v[1] = TexturedVertex(Vec3f::ZERO, 1.f, 1, 1, Vec2f::X_AXIS);
430 	v[2] = TexturedVertex(Vec3f::ZERO, 1.f, 1, 1, Vec2f(1.f, 1.f));
431 	v[3] = TexturedVertex(Vec3f::ZERO, 1.f, 1, 1, Vec2f::Y_AXIS);
432 
433 	v[0].p.z = v[1].p.z = v[2].p.z = v[3].p.z = 0.0000001f;
434 
435 	if(inventory_font) {
436 
437 		char tx[7];
438 		long tt;
439 		float ttx;
440 		float divideX = 1.f/((float) inventory_font->m_dwWidth);
441 		float divideY = 1.f/((float) inventory_font->m_dwHeight);
442 
443 		sprintf(tx, "%*ld", _iNb, num); // TODO use a safe string function.
444 		long removezero=1;
445 
446 		for(long i = 0; i < 6 && tx[i] != '\0'; i++) {
447 
448 			tt=tx[i]-'0';
449 
450 			if ((tt==0) && removezero) continue;
451 
452 			if (tt>=0)
453 			{
454 				removezero=0;
455 				v[0].p.x=v[3].p.x=x + i*INTERFACE_RATIO(10);
456 				v[1].p.x = v[2].p.x = v[0].p.x + INTERFACE_RATIO(10);
457 				v[0].p.y=v[1].p.y=y;
458 				v[2].p.y=v[3].p.y=y + INTERFACE_RATIO(10);
459 				v[0].color=v[1].color=v[2].color=v[3].color=col;
460 
461 				ttx = (float)((float)tt * (float)11.f) + 1.5f;
462 				v[3].uv.x=v[0].uv.x=ttx*divideX;
463 				v[1].uv.x=v[2].uv.x=(ttx+10.f)*divideX;
464 
465 				ttx=0.5f*divideY;
466 				v[1].uv.y = v[0].uv.y = divideY + ttx;
467 				v[2].uv.y = v[3].uv.y = divideY * 12;
468 				GRenderer->SetTexture(0, inventory_font);
469 
470 				EERIEDRAWPRIM(Renderer::TriangleFan, v, 4);
471 			}
472 		}
473 	}
474 }
475 
476 //-----------------------------------------------------------------------------
477 // Interface Texture Containers creation
478 //-----------------------------------------------------------------------------
CreateInterfaceTextureContainers()479 void CreateInterfaceTextureContainers()
480 {
481     ITC.Reset();
482 
483 	ITC.Set("aim_empty", "graph/interface/bars/aim_empty");
484 	ITC.Set("aim_maxi", "graph/interface/bars/aim_maxi");
485 	ITC.Set("aim_hit", "graph/interface/bars/flash_gauge");
486 	ITC.Set("hero_inventory", "graph/interface/inventory/hero_inventory");
487 	ITC.Set("hero_inventory_up", "graph/interface/inventory/scroll_up");
488 	ITC.Set("hero_inventory_down", "graph/interface/inventory/scroll_down");
489 	ITC.Set("hero_inventory_link", "graph/interface/inventory/hero_inventory_link");
490 	ITC.Set("inventory_pickall", "graph/interface/inventory/inv_pick");
491 	ITC.Set("inventory_close", "graph/interface/inventory/inv_close");
492 	ITC.Set("icon_lvl_up", "graph/interface/icons/lvl_up");
493 
494 	ITC.Set("backpack", "graph/interface/icons/backpack");
495 	ITC.Set("gold", "graph/interface/inventory/gold");
496 	ITC.Set("book", "graph/interface/icons/book");
497 	ITC.Set("steal", "graph/interface/icons/steal");
498 	ITC.Set("item_cant_steal", "graph/interface/icons/cant_steal_item");
499 	ITC.Set("empty_gauge_red", "graph/interface/bars/empty_gauge_red");
500 	ITC.Set("empty_gauge_blue", "graph/interface/bars/empty_gauge_blue");
501 	ITC.Set("filled_gauge_red", "graph/interface/bars/filled_gauge_red");
502 	ITC.Set("filled_gauge_blue", "graph/interface/bars/filled_gauge_blue");
503 	ITC.Set("target_on", "graph/interface/cursors/target_on");
504 	ITC.Set("target_off", "graph/interface/cursors/target_off");
505 	ITC.Set("interaction_on", "graph/interface/cursors/interaction_on");
506 	ITC.Set("interaction_off", "graph/interface/cursors/interaction_off");
507 	ITC.Set("magic", "graph/interface/cursors/magic");
508 
509 	BasicInventorySkin = TextureContainer::LoadUI("graph/interface/inventory/ingame_inventory");
510 	ThrowObject = TextureContainer::LoadUI("graph/interface/cursors/throw");
511 }
512 
513 //-----------------------------------------------------------------------------
514 
KillInterfaceTextureContainers()515 void KillInterfaceTextureContainers() {
516 	ITC.Reset();
517 }
518 
INTERFACE_TC()519 INTERFACE_TC::INTERFACE_TC()
520 {
521 }
522 
~INTERFACE_TC()523 INTERFACE_TC::~INTERFACE_TC() {
524 
525 	arx_assert(m_Textures.empty());
526 
527 	/*
528 	 * Because this is the destructor of a global object we cannot cleanup textures here.
529 	 * Doing so would mean accessing other global objects who'se destrcutors could be called before this one.
530 	 */
531 
532 }
533 
Set(const std::string & textureName,TextureContainer * pTexture)534 void INTERFACE_TC::Set(const std::string& textureName, TextureContainer* pTexture)
535 {
536 	m_Textures[textureName] = pTexture;
537 }
538 
Set(const std::string & textureName,const std::string & fileName)539 void INTERFACE_TC::Set(const std::string& textureName, const std::string& fileName)
540 {
541 	m_Textures[textureName] = TextureContainer::LoadUI(fileName.c_str());
542 }
543 
Get(const std::string & name)544 TextureContainer* INTERFACE_TC::Get(const std::string& name)
545 {
546 	TextureDictionary::iterator it = m_Textures.find(name);
547 	return it != m_Textures.end() ? (*it).second : NULL;
548 }
549 
Reset()550 void INTERFACE_TC::Reset()
551 {
552 	// For each item in the map...
553 	for(TextureDictionary::iterator it = m_Textures.begin(); it != m_Textures.end(); ++it)
554 	{
555 		// Free the textures...
556 		delete (*it).second;
557 	}
558 
559 	m_Textures.clear();
560 
561 	ITC.Level.clear();
562 	ITC.Xp.clear();
563 }
564 
DrawBookInterfaceItem(TextureContainer * tc,float x,float y,Color color=Color::white,float z=0.000001f)565 static void DrawBookInterfaceItem(TextureContainer * tc, float x, float y, Color color = Color::white, float z = 0.000001f) {
566 	if(tc) {
567 		EERIEDrawBitmap2(
568 			(x + BOOKDECX) * Xratio,
569 			(y + BOOKDECY) * Yratio,
570 			tc->m_dwWidth * Xratio,
571 			tc->m_dwHeight * Yratio,
572 			z,
573 			tc,
574 			color
575 		);
576 	}
577 }
578 
579 //-----------------------------------------------------------------------------
ARX_INTERFACE_HALO_Render(float _fR,float _fG,float _fB,long _lHaloType,TextureContainer * haloTexture,float POSX,float POSY,float fRatioX=1,float fRatioY=1)580 void ARX_INTERFACE_HALO_Render(float _fR, float _fG, float _fB,
581 							   long _lHaloType,
582 							   TextureContainer * haloTexture,
583 							   float POSX, float POSY, float fRatioX = 1, float fRatioY = 1)
584 {
585 	float power = 0.9f;
586 	power -= EEsin(arxtime.get_frame_time()*0.01f) * 0.3f;
587 
588 	_fR = clamp(_fR * power, 0, 1);
589 	_fG = clamp(_fG * power, 0, 1);
590 	_fB = clamp(_fB * power, 0, 1);
591 	Color col=Color4f(_fR,_fG,_fB).to<u8>();
592 
593 	if (_lHaloType & HALO_NEGATIVE)
594 	{
595 		GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor);
596 	}
597 	else
598 	{
599 		GRenderer->SetBlendFunc(Renderer::BlendSrcAlpha, Renderer::BlendOne);
600 	}
601 
602 	GRenderer->SetRenderState(Renderer::AlphaBlending, true);
603 
604 	float x = POSX - TextureContainer::HALO_RADIUS * fRatioX;
605 	float y = POSY - TextureContainer::HALO_RADIUS * fRatioY;
606 	float width = haloTexture->m_dwWidth * fRatioX;
607 	float height = haloTexture->m_dwHeight * fRatioY;
608 
609 	EERIEDrawBitmap(x, y, width, height, 0.00001f, haloTexture, col);
610 
611 	GRenderer->SetRenderState(Renderer::AlphaBlending, false);
612 }
613 
ARX_INTERFACE_HALO_Draw(Entity * io,TextureContainer * tc,TextureContainer * tc2,float POSX,float POSY,float _fRatioX=1,float _fRatioY=1)614 void ARX_INTERFACE_HALO_Draw(Entity * io, TextureContainer * tc, TextureContainer * tc2, float POSX, float POSY, float _fRatioX = 1, float _fRatioY = 1) {
615 	INTERFACE_HALO_NB++;
616 
617 	if(INTERFACE_HALO_NB > INTERFACE_HALO_MAX_NB) {
618 		INTERFACE_HALO_MAX_NB = INTERFACE_HALO_NB;
619 		aiHalo = (ARX_INTERFACE_HALO_STRUCT *)realloc(aiHalo,sizeof(ARX_INTERFACE_HALO_STRUCT)*INTERFACE_HALO_NB);
620 	}
621 
622 	aiHalo[INTERFACE_HALO_NB-1].io=io;
623 	aiHalo[INTERFACE_HALO_NB-1].tc=tc;
624 	aiHalo[INTERFACE_HALO_NB-1].tc2=tc2;
625 	aiHalo[INTERFACE_HALO_NB-1].POSX=POSX;
626 	aiHalo[INTERFACE_HALO_NB-1].POSY=POSY;
627 	aiHalo[INTERFACE_HALO_NB-1].fRatioX = _fRatioX;
628 	aiHalo[INTERFACE_HALO_NB-1].fRatioY = _fRatioY;
629 }
630 
ReleaseHalo()631 void ReleaseHalo() {
632 	free(aiHalo), aiHalo=NULL;
633 }
634 
ARX_INTERFACE_HALO_Flush()635 void ARX_INTERFACE_HALO_Flush() {
636 
637 	for (long i=0;i<INTERFACE_HALO_NB;i++)
638 		ARX_INTERFACE_HALO_Render(
639 		aiHalo[i].io->halo.color.r, aiHalo[i].io->halo.color.g, aiHalo[i].io->halo.color.b,
640 		aiHalo[i].io->halo.flags,
641 		aiHalo[i].tc2,aiHalo[i].POSX,aiHalo[i].POSY, aiHalo[i].fRatioX, aiHalo[i].fRatioY);
642 
643 	INTERFACE_HALO_NB=0;
644 }
645 
646 //-----------------------------------------------------------------------------
NeedHalo(Entity * io)647 bool NeedHalo(Entity * io)
648 {
649 	if (	(!io)
650 		||	(!(io->ioflags & IO_ITEM))	)
651 		return false;
652 
653 	if (io->halo.flags & HALO_ACTIVE)
654 	{
655 		if (io->inv)
656 		{
657 			io->inv->getHalo();
658 		}
659 
660 		return true;
661 	}
662 
663 	return false;
664 }
665 
666 //-----------------------------------------------------------------------------
InventoryOpenClose(unsigned long t)667 void InventoryOpenClose(unsigned long t) // 0 switch 1 forceopen 2 forceclose
668 {
669 	if ((t==1) && (player.Interface & INTER_INVENTORY)) return;
670 
671 	if ((t==2) && (!(player.Interface & INTER_INVENTORY))) return;
672 
673 	ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
674 
675 	if ((player.Interface & INTER_INVENTORY)||(player.Interface & INTER_INVENTORYALL))
676 	{
677 		bInventoryClosing = true;
678 
679 		if (WILLRETURNTOFREELOOK)
680 		{
681 			TRUE_PLAYER_MOUSELOOK_ON = true;
682 			SLID_START=float(arxtime);
683 			WILLRETURNTOFREELOOK = 0;
684 		}
685 	}
686 	else
687 	{
688 		player.Interface |= INTER_INVENTORY;
689 		InventoryY = static_cast<long>(INTERFACE_RATIO(100.f));
690 
691 		if (TRUE_PLAYER_MOUSELOOK_ON)
692 		{
693 			WILLRETURNTOFREELOOK = 1;
694 		}
695 	}
696 
697 	if ((((player.Interface & INTER_INVENTORYALL)||(TRUE_PLAYER_MOUSELOOK_ON)))&&(player.Interface & INTER_NOTE))
698 	{
699 		ARX_INTERFACE_NoteClose();
700 	}
701 
702 	if (!bInventoryClosing && config.input.autoReadyWeapon == false)
703 	{
704 		TRUE_PLAYER_MOUSELOOK_ON = false;
705 	}
706 }
707 
ARX_INTERFACE_NoteClear()708 void ARX_INTERFACE_NoteClear() {
709 	player.Interface &= ~INTER_NOTE;
710 	openNote.clear();
711 }
712 
ARX_INTERFACE_NoteOpen(gui::Note::Type type,const std::string & text)713 void ARX_INTERFACE_NoteOpen(gui::Note::Type type, const std::string & text) {
714 
715 	if(player.Interface & INTER_NOTE) {
716 		ARX_INTERFACE_NoteClose();
717 	}
718 
719 	ARX_INTERFACE_BookOpenClose(2);
720 
721 	openNote.setData(type, getLocalised(text));
722 	openNote.setPage(0);
723 
724 	player.Interface |= INTER_NOTE;
725 
726 	switch(openNote.type()) {
727 		case gui::Note::Notice:
728 			ARX_SOUND_PlayInterface(SND_MENU_CLICK, 0.9F + 0.2F * rnd());
729 			break;
730 		case gui::Note::Book:
731 			ARX_SOUND_PlayInterface(SND_BOOK_OPEN, 0.9F + 0.2F * rnd());
732 			break;
733 		case gui::Note::SmallNote:
734 		case gui::Note::BigNote:
735 			ARX_SOUND_PlayInterface(SND_SCROLL_OPEN, 0.9F + 0.2F * rnd());
736 			break;
737 		default: break;
738 	}
739 
740 	if(TRUE_PLAYER_MOUSELOOK_ON && type == gui::Note::Book) {
741 		TRUE_PLAYER_MOUSELOOK_ON = false;
742 	}
743 
744 	if(player.Interface & INTER_INVENTORYALL) {
745 		bInventoryClosing = true;
746 		ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
747 	}
748 }
749 
ARX_INTERFACE_NoteClose()750 void ARX_INTERFACE_NoteClose() {
751 
752 	if(!(player.Interface & INTER_NOTE)) {
753 		return;
754 	}
755 
756 	switch(openNote.type()) {
757 		case gui::Note::Notice: {
758 			ARX_SOUND_PlayInterface(SND_MENU_CLICK, 0.9F + 0.2F * rnd());
759 			break;
760 		}
761 		case gui::Note::Book:
762 			ARX_SOUND_PlayInterface(SND_BOOK_CLOSE, 0.9F + 0.2F * rnd());
763 			break;
764 		case gui::Note::SmallNote:
765 		case gui::Note::BigNote:
766 			ARX_SOUND_PlayInterface(SND_SCROLL_CLOSE, 0.9F + 0.2F * rnd());
767 			break;
768 		default: break;
769 	}
770 
771 	ARX_INTERFACE_NoteClear();
772 }
773 
ARX_INTERFACE_NoteManage()774 void ARX_INTERFACE_NoteManage() {
775 
776 	if(!(player.Interface & INTER_NOTE)) {
777 		return;
778 	}
779 
780 	if(gui::manageNoteActions(openNote)) {
781 		ARX_INTERFACE_NoteClose();
782 	}
783 
784 	openNote.render();
785 }
786 
onBookClosePage()787 static void onBookClosePage() {
788 
789 	if(Book_Mode == BOOKMODE_SPELLS) {
790 		// Closing spell page - clean up any rune flares
791 		ARX_SPELLS_ClearAllSymbolDraw();
792 	}
793 
794 }
795 
ARX_INTERFACE_BookOpenClose(unsigned long t)796 void ARX_INTERFACE_BookOpenClose(unsigned long t) // 0 switch 1 forceopen 2 forceclose
797 {
798 	if ((t==1) && (player.Interface & INTER_MAP)) return;
799 
800 	if ((t==2) && (!(player.Interface & INTER_MAP))) return;
801 
802 
803 	if (player.Interface & INTER_MAP)
804 	{
805 		ARX_SOUND_PlayInterface(SND_BOOK_CLOSE, 0.9F + 0.2F * rnd());
806 		SendIOScriptEvent(entities.player(),SM_BOOK_CLOSE);
807 		player.Interface &=~ INTER_MAP;
808 		g_miniMap.purgeTexContainer();
809 
810 		if(ARXmenu.mda) {
811 			for(long i = 0; i < MAX_FLYOVER; i++) {
812 				ARXmenu.mda->flyover[i].clear();
813 			}
814 			free(ARXmenu.mda);
815 			ARXmenu.mda=NULL;
816 		}
817 
818 		onBookClosePage();
819 	}
820 	else
821 	{
822 		SendIOScriptEvent(entities.player(),SM_NULL,"","book_open");
823 
824 		ARX_SOUND_PlayInterface(SND_BOOK_OPEN, 0.9F + 0.2F * rnd());
825 		SendIOScriptEvent(entities.player(),SM_BOOK_OPEN);
826 		ARX_INTERFACE_NoteClose();
827 		player.Interface |= INTER_MAP;
828 		Book_MapPage=ARX_LEVELS_GetRealNum(CURRENTLEVEL)+1;
829 
830 		if (Book_MapPage>8) Book_MapPage=8;
831 
832 		if (Book_MapPage<1) Book_MapPage=1;
833 
834 		if(!ARXmenu.mda)
835 		{
836 //			ARXmenu.mda = (MENU_DYNAMIC_DATA *)malloc(sizeof(MENU_DYNAMIC_DATA));
837 //			memset(ARXmenu.mda,0,sizeof(MENU_DYNAMIC_DATA));
838 			ARXmenu.mda = new MENU_DYNAMIC_DATA();
839 
840 			ARXmenu.mda->flyover[BOOK_STRENGTH] = getLocalised("system_charsheet_strength");
841 			ARXmenu.mda->flyover[BOOK_MIND] = getLocalised("system_charsheet_intel");
842 			ARXmenu.mda->flyover[BOOK_DEXTERITY] = getLocalised("system_charsheet_dex");
843 			ARXmenu.mda->flyover[BOOK_CONSTITUTION] = getLocalised("system_charsheet_consti");
844 			ARXmenu.mda->flyover[BOOK_STEALTH] = getLocalised("system_charsheet_stealth");
845 			ARXmenu.mda->flyover[BOOK_MECANISM] = getLocalised("system_charsheet_mecanism");
846 			ARXmenu.mda->flyover[BOOK_INTUITION] = getLocalised("system_charsheet_intuition");
847 			ARXmenu.mda->flyover[BOOK_ETHERAL_LINK] = getLocalised("system_charsheet_etheral_link");
848 			ARXmenu.mda->flyover[BOOK_OBJECT_KNOWLEDGE] = getLocalised("system_charsheet_objknoledge");
849 			ARXmenu.mda->flyover[BOOK_CASTING] = getLocalised("system_charsheet_casting");
850 			ARXmenu.mda->flyover[BOOK_PROJECTILE] = getLocalised("system_charsheet_projectile");
851 			ARXmenu.mda->flyover[BOOK_CLOSE_COMBAT] = getLocalised("system_charsheet_closecombat");
852 			ARXmenu.mda->flyover[BOOK_DEFENSE] = getLocalised("system_charsheet_defense");
853 			ARXmenu.mda->flyover[BUTTON_QUICK_GENERATION] = getLocalised("system_charsheet_quickgenerate");
854 			ARXmenu.mda->flyover[BUTTON_DONE] = getLocalised("system_charsheet_done");
855 			ARXmenu.mda->flyover[BUTTON_SKIN] = getLocalised("system_charsheet_skin");
856 			ARXmenu.mda->flyover[WND_ATTRIBUTES] = getLocalised("system_charsheet_atributes");
857 			ARXmenu.mda->flyover[WND_SKILLS] = getLocalised("system_charsheet_skills");
858 			ARXmenu.mda->flyover[WND_STATUS] = getLocalised("system_charsheet_status");
859 			ARXmenu.mda->flyover[WND_LEVEL] = getLocalised("system_charsheet_level");
860 			ARXmenu.mda->flyover[WND_XP] = getLocalised("system_charsheet_xpoints");
861 			ARXmenu.mda->flyover[WND_HP] = getLocalised("system_charsheet_hp");
862 			ARXmenu.mda->flyover[WND_MANA] = getLocalised("system_charsheet_mana");
863 			ARXmenu.mda->flyover[WND_AC] = getLocalised("system_charsheet_ac");
864 			ARXmenu.mda->flyover[WND_RESIST_MAGIC] = getLocalised("system_charsheet_res_magic");
865 			ARXmenu.mda->flyover[WND_RESIST_POISON] = getLocalised("system_charsheet_res_poison");
866 			ARXmenu.mda->flyover[WND_DAMAGE] = getLocalised("system_charsheet_damage");
867 		}
868 	}
869 
870 	if (player.Interface&INTER_COMBATMODE)
871 	{
872 		player.Interface&=~INTER_COMBATMODE;
873 		ARX_EQUIPMENT_LaunchPlayerUnReadyWeapon();
874 	}
875 
876 	if (player.Interface & INTER_INVENTORYALL)
877 	{
878 		ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
879 		bInventoryClosing = true;
880 	}
881 
882 	BOOKZOOM = 0;
883 	bBookHalo = false;
884 	ulBookHaloTime = 0;
885 	pTextManage->Clear();
886 
887 	TRUE_PLAYER_MOUSELOOK_ON = false;
888 }
889 
890 //-------------------------------------------------------------------------------------
891 // Keyboard/Mouse Management
892 //-------------------------------------------------------------------------------------
893 
ResetPlayerInterface()894 void ResetPlayerInterface() {
895 	player.Interface |= INTER_LIFE_MANA;
896 	SLID_VALUE = 0;
897 	lSLID_VALUE = 0;
898 	SLID_START=float(arxtime);
899 }
900 
ReleaseInfosCombine()901 void ReleaseInfosCombine() {
902 
903 	Entity * io = NULL;
904 
905 	if (player.bag)
906 	for (int iNbBag=0; iNbBag<player.bag; iNbBag++)
907 	for (size_t j=0;j<INVENTORY_Y;j++)
908 	for (size_t i=0;i<INVENTORY_X;i++)
909 	{
910 		io = inventory[iNbBag][i][j].io;
911 
912 		if(io)
913 		{
914 			io->ioflags&=~IO_CAN_COMBINE;
915 		}
916 	}
917 
918 	if (SecondaryInventory)
919 	{
920 		for (long j=0;j<SecondaryInventory->sizey;j++)
921 			for (long i=0;i<SecondaryInventory->sizex;i++)
922 			{
923 				io=SecondaryInventory->slot[i][j].io;
924 
925 				if ( io )
926 				{
927 					io->ioflags&=~IO_CAN_COMBINE;
928 				}
929 			}
930 	}
931 }
932 
933 //-----------------------------------------------------------------------------
findParam(char * pcToken,const char * param)934 char* findParam(char* pcToken, const char* param)
935 {
936 	char* pStartString = 0;
937 
938 	if(strstr(pcToken,"^$param1"))
939 		pStartString = strstr(pcToken, param);
940 
941 	return pStartString;
942 }
943 
GetInfosCombineWithIO(Entity * _pWithIO)944 void GetInfosCombineWithIO(Entity * _pWithIO)
945 {
946 	if(!COMBINE)
947 	{
948 		return;
949 	}
950 
951 	std::string tcIndent = COMBINE->long_name();
952 
953 		char tTxtCombineDest[256];
954 
955 		if(	(_pWithIO)&&
956 			(_pWithIO!=COMBINE)&&
957 			(_pWithIO->script.data) )
958 		{
959 			char* pCopyScript=new char[_pWithIO->script.size + 1];
960 			pCopyScript[_pWithIO->script.size] = '\0';
961 			memcpy(pCopyScript,_pWithIO->script.data,_pWithIO->script.size);
962 
963 			char* pCopyOverScript=NULL;
964 
965 			if(_pWithIO->over_script.data)
966 			{
967 				pCopyOverScript=new char[_pWithIO->over_script.size + 1];
968 				pCopyOverScript[_pWithIO->over_script.size] = '\0';
969 				memcpy(pCopyOverScript,_pWithIO->over_script.data,_pWithIO->over_script.size);
970 			}
971 
972 			char *pcFound=NULL;
973 
974 			if(pCopyOverScript)
975 			{
976 				pcFound=strstr((char*)pCopyOverScript,"on combine");
977 
978 				if(pcFound)
979 				{
980 					unsigned int uiNbOpen=0;
981 
982 					char *pcToken=strtok(pcFound,"\r\n");
983 
984 					if(strstr(pcToken,"{"))
985 					{
986 						uiNbOpen++;
987 					}
988 
989 					while(pcToken)
990 					{
991 						pcToken=strtok(NULL,"\r\n");
992 
993 						bool bCanCombine=false;
994 						char* pStartString;
995 						char* pEndString;
996 
997 						pStartString = findParam(pcToken, "isclass");
998 						if(pStartString)
999 						{
1000 							pStartString=strstr(pStartString,"\"");
1001 
1002 							if(pStartString)
1003 							{
1004 								pStartString++;
1005 								pEndString=strstr(pStartString,"\"");
1006 
1007 								if(pEndString)
1008 								{
1009 									memcpy(tTxtCombineDest,pStartString,pEndString-pStartString);
1010 									tTxtCombineDest[pEndString-pStartString]=0;
1011 
1012 									if(tTxtCombineDest == COMBINE->short_name()) {
1013 										//same class
1014 										bCanCombine=true;
1015 									}
1016 								}
1017 							}
1018 						}
1019 						else
1020 						{
1021 							pStartString = findParam(pcToken, "==");
1022 							if(pStartString)
1023 							{
1024 								pStartString=strstr(pStartString,"\"");
1025 
1026 								if(pStartString)
1027 								{
1028 									pStartString++;
1029 									pEndString=strstr(pStartString,"\"");
1030 
1031 									if(pEndString)
1032 									{
1033 										memcpy(tTxtCombineDest,pStartString,pEndString-pStartString);
1034 										tTxtCombineDest[pEndString-pStartString]=0;
1035 
1036 										if(tTxtCombineDest == tcIndent)
1037 										{
1038 											//same class
1039 											bCanCombine=true;
1040 										}
1041 									}
1042 								}
1043 							}
1044 							else
1045 							{
1046 								pStartString = findParam(pcToken, "isgroup");
1047 								if(pStartString)
1048 								{
1049 									pStartString=strstr(pStartString," ");
1050 
1051 									if(pStartString)
1052 									{
1053 										pStartString++;
1054 										pEndString=strstr(pStartString," ");
1055 										char* pEndString2=strstr(pStartString,")");
1056 
1057 										if(pEndString2<pEndString)
1058 										{
1059 											pEndString=pEndString2;
1060 										}
1061 
1062 										if(pEndString)
1063 										{
1064 											memcpy(tTxtCombineDest,pStartString,pEndString-pStartString);
1065 											tTxtCombineDest[pEndString-pStartString]=0;
1066 											if(COMBINE->groups.find(tTxtCombineDest) != COMBINE->groups.end()) {
1067 													//same class
1068 													bCanCombine = true;
1069 											}
1070 										}
1071 									}
1072 								}
1073 							}
1074 						}
1075 
1076 						if(strstr(pcToken,"{"))
1077 						{
1078 							uiNbOpen++;
1079 						}
1080 
1081 						if(strstr(pcToken,"}"))
1082 						{
1083 							uiNbOpen--;
1084 						}
1085 
1086 						if(bCanCombine)
1087 						{
1088 							uiNbOpen=0;
1089 							_pWithIO->ioflags|=IO_CAN_COMBINE;
1090 						}
1091 						else
1092 						{
1093 							_pWithIO->ioflags&=~IO_CAN_COMBINE;
1094 						}
1095 
1096 						if(!uiNbOpen)
1097 						{
1098 							break;
1099 						}
1100 					}
1101 				}
1102 			}
1103 
1104 			if(_pWithIO->ioflags&IO_CAN_COMBINE)
1105 			{
1106 				delete[] pCopyScript;
1107 				delete[] pCopyOverScript;
1108 				return;
1109 			}
1110 
1111 			pcFound=strstr((char*)pCopyScript,"on combine");
1112 
1113 			if(pcFound)
1114 			{
1115 				unsigned int uiNbOpen=0;
1116 
1117 				char *pcToken=strtok(pcFound,"\r\n");
1118 
1119 				if(strstr(pcToken,"{"))
1120 				{
1121 					uiNbOpen++;
1122 				}
1123 
1124 				while(pcToken)
1125 				{
1126 					pcToken=strtok(NULL,"\r\n");
1127 
1128 					bool bCanCombine=false;
1129 					char* pStartString;
1130 					char* pEndString;
1131 
1132 					pStartString = findParam(pcToken, "isclass");
1133 					if(pStartString)
1134 					{
1135 						pStartString=strstr(pStartString,"\"");
1136 
1137 						if(pStartString)
1138 						{
1139 							pStartString++;
1140 							pEndString=strstr(pStartString,"\"");
1141 
1142 							if(pEndString)
1143 							{
1144 								memcpy(tTxtCombineDest,pStartString,pEndString-pStartString);
1145 								tTxtCombineDest[pEndString-pStartString]=0;
1146 
1147 								if(tTxtCombineDest == COMBINE->short_name()) {
1148 									//same class
1149 									bCanCombine=true;
1150 								}
1151 							}
1152 						}
1153 					}
1154 					else
1155 					{
1156 						pStartString = findParam(pcToken, "==");
1157 						if(pStartString)
1158 						{
1159 							pStartString=strstr(pStartString,"\"");
1160 
1161 							if(pStartString)
1162 							{
1163 								pStartString++;
1164 								pEndString=strstr(pStartString,"\"");
1165 
1166 								if(pEndString)
1167 								{
1168 									memcpy(tTxtCombineDest,pStartString,pEndString-pStartString);
1169 									tTxtCombineDest[pEndString-pStartString]=0;
1170 
1171 									if(tTxtCombineDest == tcIndent) {
1172 										//same class
1173 										bCanCombine=true;
1174 									}
1175 								}
1176 							}
1177 						}
1178 						else
1179 						{
1180 							pStartString = findParam(pcToken, "isgroup");
1181 							if(pStartString)
1182 							{
1183 								pStartString=strstr(pStartString," ");
1184 
1185 								if(pStartString)
1186 								{
1187 									pStartString++;
1188 									pEndString=strstr(pStartString," ");
1189 									char* pEndString2=strstr(pStartString,")");
1190 
1191 									if(pEndString2<pEndString)
1192 									{
1193 										pEndString=pEndString2;
1194 									}
1195 
1196 									if(pEndString)
1197 									{
1198 										memcpy(tTxtCombineDest,pStartString,pEndString-pStartString);
1199 										tTxtCombineDest[pEndString-pStartString]=0;
1200 
1201 										if(COMBINE->groups.find(tTxtCombineDest) != COMBINE->groups.end()) {
1202 											// same class
1203 											bCanCombine = true;
1204 										}
1205 									}
1206 								}
1207 							}
1208 						}
1209 					}
1210 
1211 					if(strstr(pcToken,"{"))
1212 					{
1213 						uiNbOpen++;
1214 					}
1215 
1216 					if(strstr(pcToken,"}"))
1217 					{
1218 						uiNbOpen--;
1219 					}
1220 
1221 					if(bCanCombine)
1222 					{
1223 						uiNbOpen=0;
1224 						_pWithIO->ioflags|=IO_CAN_COMBINE;
1225 					}
1226 					else
1227 					{
1228 						_pWithIO->ioflags&=~IO_CAN_COMBINE;
1229 					}
1230 
1231 					if(!uiNbOpen)
1232 					{
1233 						break;
1234 					}
1235 				}
1236 			}
1237 
1238 			delete[] pCopyScript;
1239 			delete[] pCopyOverScript;
1240 		}
1241 }
1242 
1243 //-------------------------------------------------------------------------------
GetInfosCombine()1244 void GetInfosCombine()
1245 {
1246 	Entity * io = NULL;
1247 
1248 	if (player.bag)
1249 	for (int iNbBag=0; iNbBag<player.bag; iNbBag++)
1250 	for (size_t j=0;j<INVENTORY_Y;j++)
1251 	for (size_t i=0;i<INVENTORY_X;i++)
1252 	{
1253 		io = inventory[iNbBag][i][j].io;
1254 		GetInfosCombineWithIO(io);
1255 	}
1256 
1257 	if (SecondaryInventory)
1258 	{
1259 		for (long j=0;j<SecondaryInventory->sizey;j++)
1260 		{
1261 			for (long i=0;i<SecondaryInventory->sizex;i++)
1262 			{
1263 				io=SecondaryInventory->slot[i][j].io;
1264 				GetInfosCombineWithIO(io);
1265 			}
1266 		}
1267 	}
1268 }
1269 
1270 //-----------------------------------------------------------------------------
ManageEditorControls()1271 bool ArxGame::ManageEditorControls()
1272 {
1273 	Vec3f trans;
1274 
1275 	eMouseState = MOUSE_IN_WORLD;
1276 
1277 	if (TRUE_PLAYER_MOUSELOOK_ON && (config.input.autoReadyWeapon == false) && (config.input.mouseLookToggle))
1278 	{
1279 
1280 		float fX =  DANAESIZX * 0.5f;
1281 		float fY =	DANAESIZY * 0.5f;
1282 		DANAEMouse.x = checked_range_cast<short>(fX);
1283 		DANAEMouse.y = checked_range_cast<short>(fY);
1284 
1285 
1286 	}
1287 
1288 
1289 	/////////////////////////////////////////////////////
1290 	// begining to count time for sliding interface
1291 	if ((!PLAYER_INTERFACE_HIDE_COUNT) && (SMOOTHSLID==0))
1292 	{
1293 		bool bOk = true;
1294 
1295 		if (TRUE_PLAYER_MOUSELOOK_ON)
1296 		{
1297 			if (!(player.Interface & INTER_COMBATMODE) && (player.doingmagic!=2) && !InInventoryPos(&DANAEMouse))
1298 			{
1299 				bOk = false;
1300 
1301 				float t=float(arxtime);
1302 
1303 				if (t-SLID_START>10000.f)
1304 				{
1305 					SLID_VALUE+=(float)Original_framedelay*( 1.0f / 10 );
1306 
1307 					if (SLID_VALUE>100.f) SLID_VALUE=100.f;
1308 
1309 					lSLID_VALUE = SLID_VALUE;
1310 				}
1311 				else
1312 				{
1313 					bOk = true;
1314 
1315 				}
1316 
1317 			}
1318 		}
1319 
1320 		if (bOk)
1321 		{
1322 			SLID_VALUE-=(float)Original_framedelay*( 1.0f / 10 );
1323 
1324 			if (SLID_VALUE<0.f) SLID_VALUE=0.f;
1325 
1326 			lSLID_VALUE = SLID_VALUE;
1327 		}
1328 	}
1329 
1330 	// on ferme
1331 	if ((player.Interface & INTER_COMBATMODE) || (player.doingmagic>=2))
1332 	{
1333 		Entity * io = NULL;
1334 
1335 		if (SecondaryInventory!=NULL)
1336 		{
1337 			io = (Entity *)SecondaryInventory->io;
1338 		}
1339 		else if (player.Interface & INTER_STEAL)
1340 		{
1341 			io = ioSteal;
1342 		}
1343 
1344 		if (io!=NULL)
1345 		{
1346 			InventoryDir=-1;
1347 			SendIOScriptEvent(io,SM_INVENTORY2_CLOSE);
1348 			TSecondaryInventory=SecondaryInventory;
1349 			SecondaryInventory=NULL;
1350 
1351 		}
1352 	}
1353 
1354 
1355 	if (SMOOTHSLID==1)
1356 	{
1357 		SLID_VALUE+=(float)Original_framedelay*( 1.0f / 10 );
1358 
1359 		if (SLID_VALUE > 100.f)
1360 		{
1361 			SLID_VALUE = 100.f;
1362 			SMOOTHSLID = 0;
1363 		}
1364 
1365 		lSLID_VALUE = SLID_VALUE;
1366 	}
1367 	else if (SMOOTHSLID==-1)
1368 	{
1369 		SLID_VALUE-=(float)Original_framedelay*( 1.0f / 10 );
1370 
1371 		if (SLID_VALUE < 0.f)
1372 		{
1373 			SLID_VALUE = 0.f;
1374 			SMOOTHSLID = 0;
1375 		}
1376 
1377 		lSLID_VALUE = SLID_VALUE;
1378 	}
1379 
1380 	if (CINEMA_INC==1)
1381 	{
1382 		CINEMA_DECAL+=(float)Original_framedelay*( 1.0f / 10 );
1383 
1384 		if (CINEMA_DECAL > 100.f)
1385 		{
1386 			CINEMA_DECAL = 100.f;
1387 			CINEMA_INC = 0;
1388 		}
1389 	}
1390 	else if (CINEMA_INC==-1)
1391 	{
1392 		CINEMA_DECAL-=(float)Original_framedelay*( 1.0f / 10 );
1393 
1394 		if (CINEMA_DECAL < 0.f)
1395 		{
1396 			CINEMA_DECAL = 0.f;
1397 			CINEMA_INC = 0;
1398 		}
1399 	}
1400 
1401 	/////////////////////////////////////////////////////
1402 
1403 	if(EERIEMouseButton & 1) {
1404 		static Vec2s dragThreshold = Vec2s::ZERO;
1405 
1406 		if(!(LastMouseClick & 1)) {
1407 
1408 			STARTDRAG = DANAEMouse;
1409 			DRAGGING = 0;
1410 			dragThreshold = Vec2s::ZERO;
1411 
1412 		} else {
1413 
1414 			dragThreshold += GInput->getMousePosRel();
1415 			if((abs(DANAEMouse.x - STARTDRAG.x) > 2 && abs(DANAEMouse.y - STARTDRAG.y) > 2)
1416 			   || (abs(dragThreshold.x) > 2 || abs(dragThreshold.y) > 2)) {
1417 				DRAGGING = 1;
1418 			}
1419 		}
1420 
1421 	} else {
1422 		DRAGGING = 0;
1423 	}
1424 
1425 	//-------------------------------------------------------------------------
1426 	// interface
1427 	//-------------------------------------------------------------------------
1428 	// torch
1429 	float px = 0;
1430 	float py = 0;
1431 
1432 	if (!BLOCK_PLAYER_CONTROLS)
1433 	{
1434 		if ((!(player.Interface & INTER_COMBATMODE)))
1435 		{
1436 
1437 			if (!TRUE_PLAYER_MOUSELOOK_ON)
1438 			{
1439 				px = INTERFACE_RATIO(InventoryX) + INTERFACE_RATIO(110);
1440 
1441 				if (px < INTERFACE_RATIO(10)) px = INTERFACE_RATIO(10);
1442 
1443 				py = DANAESIZY - INTERFACE_RATIO(158+32);
1444 
1445 				if (CURRENT_TORCH != NULL)
1446 				{
1447 					if (MouseInRect(px,py, px + INTERFACE_RATIO(32), py + INTERFACE_RATIO(64)))
1448 					{
1449 						eMouseState=MOUSE_IN_TORCH_ICON;
1450 						SpecialCursor=CURSOR_INTERACTION_ON;
1451 
1452 						if ((LastMouseClick & 1) && (!(EERIEMouseButton & 1)) )
1453 						{
1454 							Entity * temp = CURRENT_TORCH;
1455 
1456 							if(temp && !temp->locname.empty()) {
1457 
1458 								if (((CURRENT_TORCH->ioflags & IO_ITEM) && CURRENT_TORCH->_itemdata->equipitem)
1459 									&& (player.Full_Skill_Object_Knowledge + player.Full_Attribute_Mind
1460 									>= CURRENT_TORCH->_itemdata->equipitem->elements[IO_EQUIPITEM_ELEMENT_Identify_Value].value) )
1461 								{
1462 									SendIOScriptEvent(FlyingOverIO,SM_IDENTIFY);
1463 								}
1464 
1465 								WILLADDSPEECH = getLocalised(temp->locname);
1466 
1467 								if (temp->ioflags & IO_GOLD)
1468 								{
1469 									std::stringstream ss;
1470 									ss << temp->_itemdata->price << " " << WILLADDSPEECH;
1471 									WILLADDSPEECH = ss.str();
1472 								}
1473 
1474 								if ((temp->poisonous>0) && (temp->poisonous_count!=0))
1475 								{
1476 									std::string Text = getLocalised("description_poisoned", "error");
1477 									std::stringstream ss;
1478 									ss << WILLADDSPEECH << " (" << Text << " " << (int)temp->poisonous << ")";
1479 									WILLADDSPEECH = ss.str();
1480 								}
1481 
1482 								if ((temp->ioflags & IO_ITEM) && (temp->durability<100.f))
1483 								{
1484 									std::string Text = getLocalised("description_durability", "error");
1485 									std::stringstream ss;
1486 									ss << WILLADDSPEECH << " " << Text << " " << std::fixed << std::setw(3) << std::setprecision(0) << temp->durability << std::setw(0) << "/" << std::setw(3) << temp->max_durability;
1487 									WILLADDSPEECH = ss.str();
1488 								}
1489 
1490 
1491 								WILLADDSPEECHTIME = (unsigned long)(arxtime);
1492 							}
1493 						}
1494 
1495 						if  ((EERIEMouseButton & 1) && (LastMouseClick &1))
1496 						{
1497 							if ( (abs(DANAEMouse.x-STARTDRAG.x)>2) ||
1498 								(abs(DANAEMouse.y-STARTDRAG.y)>2) )	DRAGGING = 1;
1499 						}
1500 
1501 						if ((DRAGINTER == NULL)  && (!PLAYER_MOUSELOOK_ON) && DRAGGING)
1502 						{
1503 							Entity * io=CURRENT_TORCH;
1504 							CURRENT_TORCH->show=SHOW_FLAG_IN_SCENE;
1505 							ARX_SOUND_PlaySFX(SND_TORCH_END);
1506 							ARX_SOUND_Stop(SND_TORCH_LOOP);
1507 							CURRENT_TORCH=NULL;
1508 							SHOW_TORCH=0;
1509 							DynLight[0].exist=0;
1510 							Set_DragInter(io);
1511 							DRAGINTER->ignition=1;
1512 						}
1513 						else
1514 						{
1515 							if ((EERIEMouseButton & 4) && (COMBINE == NULL))
1516 							{
1517 								COMBINE = CURRENT_TORCH;
1518 							}
1519 
1520 							if (!(EERIEMouseButton & 2) && (LastMouseClick & 2))
1521 							{
1522 								ARX_PLAYER_ClickedOnTorch(CURRENT_TORCH);
1523 								EERIEMouseButton &= ~2;
1524 								TRUE_PLAYER_MOUSELOOK_ON = false;
1525 							}
1526 						}
1527 					}
1528 				}
1529 
1530 				// redist
1531 				if ((player.Skill_Redistribute) || (player.Attribute_Redistribute))
1532 				{
1533 					px = DANAESIZX - INTERFACE_RATIO(35) + lSLID_VALUE + GL_DECAL_ICONS;
1534 					py = DANAESIZY - INTERFACE_RATIO(218);
1535 
1536 					if (MouseInRect(px, py, px + INTERFACE_RATIO(32), py + INTERFACE_RATIO(32)))
1537 					{
1538 						eMouseState=MOUSE_IN_REDIST_ICON;
1539 						SpecialCursor=CURSOR_INTERACTION_ON;
1540 
1541 						if ((EERIEMouseButton & 1) && !(LastMouseClick & 1))
1542 						{
1543 							ARX_INTERFACE_BookOpenClose(1);
1544 							EERIEMouseButton &=~1;
1545 						}
1546 
1547 						return false;
1548 					}
1549 				}
1550 
1551 
1552 				// gold
1553 				if (player.gold>0)
1554 				{
1555 					px = DANAESIZX - INTERFACE_RATIO(35) + lSLID_VALUE + GL_DECAL_ICONS;
1556 					py = DANAESIZY - INTERFACE_RATIO(183);
1557 
1558 					if (MouseInRect(px,py, px + INTERFACE_RATIO(32), py + INTERFACE_RATIO(32)))
1559 					{
1560 						eMouseState=MOUSE_IN_GOLD_ICON;
1561 						SpecialCursor=CURSOR_INTERACTION_ON;
1562 
1563 						if ((player.gold > 0)
1564 							&& (!GInput->actionPressed(CONTROLS_CUST_MAGICMODE))
1565 							&& (COMBINE==NULL) && (!COMBINEGOLD))
1566 						{
1567 							if (EERIEMouseButton & 4)
1568 								COMBINEGOLD=1;
1569 						}
1570 
1571 						if (DRAGINTER == NULL)
1572 							return false;
1573 					}
1574 				}
1575 
1576 				// book
1577 				px = DANAESIZX - INTERFACE_RATIO(35) + lSLID_VALUE + GL_DECAL_ICONS;
1578 				py = DANAESIZY - INTERFACE_RATIO(148);
1579 
1580 				if (MouseInRect(px, py, px + INTERFACE_RATIO(32), py + INTERFACE_RATIO(32)))
1581 				{
1582 					eMouseState=MOUSE_IN_BOOK_ICON;
1583 					SpecialCursor=CURSOR_INTERACTION_ON;
1584 
1585 					if ((EERIEMouseButton & 1) && !(LastMouseClick & 1))
1586 					{
1587 						ARX_INTERFACE_BookOpenClose(0);
1588 						EERIEMouseButton &=~1;
1589 					}
1590 
1591 					return false;
1592 				}
1593 
1594 				// inventaire
1595 				px = DANAESIZX - INTERFACE_RATIO(35) + lSLID_VALUE + GL_DECAL_ICONS;
1596 				py = DANAESIZY - INTERFACE_RATIO(113);
1597 				static float flDelay=0;
1598 
1599 				if (MouseInRect(px, py, px + INTERFACE_RATIO(32), py + INTERFACE_RATIO(32))||flDelay)
1600 				{
1601 					eMouseState=MOUSE_IN_INVENTORY_ICON;
1602 					SpecialCursor=CURSOR_INTERACTION_ON;
1603 
1604 					if (EERIEMouseButton & 4)
1605 					{
1606 						ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
1607 
1608 						playerInventory.optimize();
1609 
1610 						flDelay=0;
1611 						EERIEMouseButton&=~4;
1612 					}
1613 					else if (((EERIEMouseButton & 1) && !(LastMouseClick & 1)) || flDelay)
1614 					{
1615 						if (!flDelay)
1616 						{
1617 							flDelay=arxtime.get_updated();
1618 							return false;
1619 						}
1620 						else
1621 						{
1622 							if ((arxtime.get_updated() - flDelay) < 300)
1623 							{
1624 								return false;
1625 							}
1626 							else
1627 							{
1628 								flDelay=0;
1629 							}
1630 						}
1631 
1632 						if (player.Interface & INTER_INVENTORYALL)
1633 						{
1634 							ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
1635 							bInventoryClosing = true;
1636 
1637 						}
1638 						else
1639 						{
1640 							bInverseInventory=!bInverseInventory;
1641 							lOldTruePlayerMouseLook=TRUE_PLAYER_MOUSELOOK_ON;
1642 						}
1643 
1644 						EERIEMouseButton &=~1;
1645 					}
1646 					else if ((EERIEMouseButton & 2) && !(LastMouseClick & 2))
1647 					{
1648 						ARX_INTERFACE_BookOpenClose(2);
1649 						ARX_INVENTORY_OpenClose(NULL);
1650 
1651 						if (player.Interface & INTER_INVENTORYALL)
1652 						{
1653 							bInventoryClosing = true;
1654 						}
1655 						else
1656 						{
1657 							if ((player.Interface & INTER_INVENTORY))
1658 							{
1659 								ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
1660 								bInventoryClosing = true;
1661 								bInventorySwitch = true;
1662 							}
1663 							else
1664 							{
1665 								ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
1666 								player.Interface |= INTER_INVENTORYALL;
1667 
1668 								float fInventoryY = INTERFACE_RATIO(121.f) * (player.bag);
1669 								InventoryY = checked_range_cast<long>(fInventoryY);
1670 
1671 								ARX_INTERFACE_NoteClose();
1672 
1673 								if (TRUE_PLAYER_MOUSELOOK_ON)
1674 								{
1675 									WILLRETURNTOFREELOOK = 1;
1676 								}
1677 							}
1678 						}
1679 
1680 						EERIEMouseButton &= ~2;
1681 						TRUE_PLAYER_MOUSELOOK_ON = false;
1682 					}
1683 
1684 					if (DRAGINTER == NULL)
1685 						return false;
1686 				}
1687 			}
1688 
1689 			// steal
1690 			if (player.Interface & INTER_STEAL)
1691 			{
1692 				px = static_cast<float>(-lSLID_VALUE);
1693 				py = DANAESIZY - INTERFACE_RATIO(78 + 32);
1694 
1695 				if (MouseInRect(px, py, px + INTERFACE_RATIO(32), py + INTERFACE_RATIO(32)))
1696 				{
1697 					eMouseState=MOUSE_IN_STEAL_ICON;
1698 					SpecialCursor=CURSOR_INTERACTION_ON;
1699 
1700 					if ((EERIEMouseButton & 1) && !(LastMouseClick & 1))
1701 					{
1702 						ARX_INVENTORY_OpenClose(ioSteal);
1703 
1704 						if (player.Interface&(INTER_INVENTORY | INTER_INVENTORYALL))
1705 						{
1706 							ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
1707 						}
1708 
1709 						if (SecondaryInventory != NULL)
1710 						{
1711 							SendIOScriptEvent(ioSteal, SM_STEAL);
1712 
1713 							bForceEscapeFreeLook=true;
1714 						    lOldTruePlayerMouseLook=!TRUE_PLAYER_MOUSELOOK_ON;
1715 						}
1716 
1717 						EERIEMouseButton &=~1;
1718 					}
1719 
1720 					if (DRAGINTER == NULL)
1721 						return false;
1722 				}
1723 			}
1724 		}
1725 	}
1726 
1727 	// gros player book
1728 	if (player.Interface & INTER_MAP)
1729 	{
1730 		px = 97 * Xratio;
1731 		py = 64 * Yratio;
1732 
1733 		TextureContainer* playerbook = ITC.Get("playerbook");
1734 		if (playerbook)
1735 		{
1736 			if (MouseInRect(px, py, px + playerbook->m_dwWidth * Xratio, py + playerbook->m_dwHeight * Yratio))
1737 			{
1738 				eMouseState = MOUSE_IN_BOOK;
1739 			}
1740 		}
1741 	}
1742 
1743 	// gros book/note
1744 	if(player.Interface & INTER_NOTE) {
1745 		if(openNote.area().contains(Vec2f(DANAEMouse))) {
1746 			eMouseState = MOUSE_IN_NOTE;
1747 			return false;
1748 		}
1749 	}
1750 
1751 	if (!PLAYER_INTERFACE_HIDE_COUNT && (TSecondaryInventory!=NULL))
1752 	{
1753 		px = INTERFACE_RATIO(InventoryX) + INTERFACE_RATIO(16);
1754 		py = INTERFACE_RATIO_DWORD(BasicInventorySkin->m_dwHeight) - INTERFACE_RATIO(16);
1755 		Entity * temp=(Entity *)TSecondaryInventory->io;
1756 
1757 		if (temp && !(temp->ioflags & IO_SHOP) && !(temp == ioSteal))
1758 		{
1759 			if (MouseInRect(px,py, px + INTERFACE_RATIO(16), py + INTERFACE_RATIO(16)))
1760 			{
1761 				eMouseState = MOUSE_IN_INVENTORY_PICKALL_ICON;
1762 				SpecialCursor=CURSOR_INTERACTION_ON;
1763 
1764 				if ((EERIEMouseButton & 1) && !(LastMouseClick & 1))
1765 				{
1766 					if (TSecondaryInventory)
1767 					{
1768 						// play un son que si un item est pris
1769 						ARX_INVENTORY_TakeAllFromSecondaryInventory();
1770 					}
1771 
1772 					EERIEMouseButton &=~1;
1773 				}
1774 
1775 				if (DRAGINTER == NULL)
1776 					return false;
1777 			}
1778 		}
1779 
1780 		//py = 20;
1781 		px = INTERFACE_RATIO(InventoryX) + INTERFACE_RATIO_DWORD(BasicInventorySkin->m_dwWidth) - INTERFACE_RATIO(32);
1782 
1783 		if (MouseInRect(px,py, px + INTERFACE_RATIO(16), py + INTERFACE_RATIO(16)))
1784 		{
1785 			eMouseState = MOUSE_IN_INVENTORY_CLOSE_ICON;
1786 			SpecialCursor=CURSOR_INTERACTION_ON;
1787 
1788 			if ((EERIEMouseButton & 1) && !(LastMouseClick & 1))
1789 			{
1790 				Entity * io = NULL;
1791 
1792 				if (SecondaryInventory!=NULL)
1793 				{
1794 					io = (Entity *)SecondaryInventory->io;
1795 				}
1796 				else if (player.Interface & INTER_STEAL)
1797 				{
1798 					io = ioSteal;
1799 				}
1800 
1801 				if (io!=NULL)
1802 				{
1803 					ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
1804 					InventoryDir=-1;
1805 					SendIOScriptEvent(io,SM_INVENTORY2_CLOSE);
1806 					TSecondaryInventory=SecondaryInventory;
1807 					SecondaryInventory=NULL;
1808 				}
1809 
1810 				EERIEMouseButton &=~1;
1811 			}
1812 
1813 			if (DRAGINTER == NULL)
1814 				return false;
1815 		}
1816 	}
1817 
1818 	//-------------------------------------------------------------------------
1819 
1820 
1821 	// Single Click On Object
1822 	if ( ( LastMouseClick & 1 ) && ( !( EERIEMouseButton & 1 ) ) )
1823 	{
1824 		if ( FlyingOverIO && ( !DRAGINTER ) )
1825 		{
1826 			SendIOScriptEvent( FlyingOverIO, SM_CLICKED );
1827 			bool bOk = true;
1828 
1829 			if ( SecondaryInventory != NULL )
1830 			{
1831 				Entity * temp = (Entity *)SecondaryInventory->io;
1832 
1833 				if (IsInSecondaryInventory(FlyingOverIO))
1834 					if ( temp->ioflags & IO_SHOP )
1835 						bOk = false;
1836 			}
1837 
1838 			if ( !( FlyingOverIO->ioflags & IO_MOVABLE ) )
1839 				if ( ( FlyingOverIO->ioflags & IO_ITEM ) && bOk )
1840 				{
1841 					if ( GInput->actionPressed( CONTROLS_CUST_STEALTHMODE ) )
1842 					{
1843 						if ( !InPlayerInventoryPos( &DANAEMouse ) && !ARX_INTERFACE_MouseInBook() )
1844 						{
1845 							long sx, sy;
1846 							bool bSecondary = false;
1847 
1848 							sx = sy = 0 ;
1849 
1850 							if ( TSecondaryInventory && IsInSecondaryInventory( FlyingOverIO ) )
1851 							{
1852 								if ( SecondaryInventory )
1853 								{
1854 									bool bfound = true;
1855 
1856 									for ( long j = 0 ; j < SecondaryInventory->sizey && bfound ; j++ )
1857 									{
1858 										for ( long i = 0 ; i < SecondaryInventory->sizex && bfound ; i++ )
1859 										{
1860 											if ( SecondaryInventory->slot[i][j].io == FlyingOverIO )
1861 											{
1862 												sx		= i;
1863 												sy		= j;
1864 												bfound	= false;
1865 											}
1866 										}
1867 									}
1868 
1869 									if (bfound) ARX_DEAD_CODE();
1870 								}
1871 
1872 								bSecondary = true;
1873 							}
1874 
1875 							RemoveFromAllInventories( FlyingOverIO );
1876 							FlyingOverIO->show = SHOW_FLAG_IN_INVENTORY;
1877 
1878 							if ( FlyingOverIO->ioflags & IO_GOLD )
1879 							{
1880 								ARX_SOUND_PlayInterface( SND_GOLD );
1881 							}
1882 
1883 							ARX_SOUND_PlayInterface( SND_INVSTD );
1884 
1885 							if(!playerInventory.insert(FlyingOverIO)) {
1886 
1887 								if ( TSecondaryInventory && bSecondary )
1888 								{
1889 									extern short sInventory, sInventoryX, sInventoryY;
1890 									sInventory = 2;
1891 									sInventoryX = checked_range_cast<short>(sx);
1892 									sInventoryY = checked_range_cast<short>(sy);
1893 
1894 									CanBePutInSecondaryInventory( TSecondaryInventory, FlyingOverIO, &sx, &sy );
1895 								}
1896 
1897 								if ( !bSecondary )
1898 								{
1899 									FlyingOverIO->show = SHOW_FLAG_IN_SCENE;
1900 								}
1901 							}
1902 
1903 							if (DRAGINTER == FlyingOverIO)
1904 							{
1905 								DRAGINTER = NULL;
1906 							}
1907 
1908 							FlyingOverIO = NULL;
1909 						}
1910 					}
1911 				}
1912 		}
1913 	}
1914 
1915 	if (!(player.Interface & INTER_COMBATMODE))
1916 	{
1917 		// Dropping an Interactive Object that has been dragged
1918 		if ((!(EERIEMouseButton & 1)) && (LastMouseClick & 1) && (DRAGINTER!=NULL))
1919 		{
1920 			//if (ARX_EQUIPMENT_PutOnPlayer(DRAGINTER))
1921 			if (InInventoryPos(&DANAEMouse)) // Attempts to put it in inventory
1922 			{
1923 				if (!PutInInventory())
1924 				{
1925 				}
1926 			}
1927 			else if (eMouseState == MOUSE_IN_INVENTORY_ICON)
1928 			{
1929 				if (!PutInInventory())
1930 				{
1931 				}
1932 			}
1933 			else if (ARX_INTERFACE_MouseInBook())
1934 			{
1935 				if (Book_Mode == BOOKMODE_STATS)
1936 				{
1937 					SendIOScriptEvent(DRAGINTER,SM_INVENTORYUSE);
1938 					COMBINE=NULL;
1939 				}
1940 			} else if (DRAGINTER->ioflags & IO_GOLD) {
1941 				ARX_PLAYER_AddGold(DRAGINTER);
1942 				Set_DragInter(NULL);
1943 
1944 			} else if(DRAGINTER) {
1945 #ifdef BUILD_EDITOR
1946 				if (!EDITMODE) // test for NPC & FIX
1947 				{
1948 					if ((DRAGINTER->ioflags & IO_NPC) || (DRAGINTER->ioflags & IO_FIX) )
1949 					{
1950 						Set_DragInter(NULL);
1951 						goto suivant2;
1952 					}
1953 				}
1954 #endif
1955 
1956 				if (!((DRAGINTER->ioflags & IO_ITEM) && (DRAGINTER->_itemdata->count > 1)))
1957 					if ((DRAGINTER->obj) && (DRAGINTER->obj->pbox))
1958 					{
1959 
1960 						if (
1961 							(!InInventoryPos(&DANAEMouse))) //Put object in fromt of player
1962 						{
1963 							if (ARX_MOUSE_OVER & ARX_MOUSE_OVER_BOOK)
1964 								 goto suivant2;
1965 
1966 							long res=Manage3DCursor(0);
1967 
1968 						if (res==0) // Throw Object
1969 						{
1970 							Entity * io=DRAGINTER;
1971 							ARX_PLAYER_Remove_Invisibility();
1972 							io->obj->pbox->active=1;
1973 							io->obj->pbox->stopcount=0;
1974 							Vec3f pos = io->pos = player.pos + Vec3f(0.f, 80.f, 0.f);
1975 							io->velocity = Vec3f::ZERO;
1976 							io->stopped = 1;
1977 							float y_ratio=(float)((float)DANAEMouse.y-(float)DANAECENTERY)/(float)DANAESIZY*2;
1978 							float x_ratio=-(float)((float)DANAEMouse.x-(float)DANAECENTERX)/(float)DANAECENTERX;
1979 							Vec3f viewvector;
1980 							viewvector.x=-(float)EEsin(radians(player.angle.b+(x_ratio*30.f)))*EEcos(radians(player.angle.a));
1981 								viewvector.y = EEsin(radians(player.angle.a)) + y_ratio;
1982 							viewvector.z= (float)EEcos(radians(player.angle.b+(x_ratio*30.f)))*EEcos(radians(player.angle.a));
1983 							io->soundtime=0;
1984 							io->soundcount=0;
1985 							EERIE_PHYSICS_BOX_Launch(io->obj,&pos,&viewvector);
1986 							ARX_SOUND_PlaySFX(SND_WHOOSH, &pos);
1987 							io->show=SHOW_FLAG_IN_SCENE;
1988 							Set_DragInter(NULL);
1989 						}
1990 				}
1991 						}
1992 
1993 			suivant2:
1994 				;
1995 						}
1996 					}
1997 
1998 	if (COMBINE)
1999 	{
2000 		if ((!CURRENT_TORCH) || (CURRENT_TORCH && (COMBINE != CURRENT_TORCH)))
2001 		{
2002 			Vec3f pos;
2003 
2004 			if (GetItemWorldPosition(COMBINE,&pos))
2005 			{
2006 				if(fartherThan(pos, player.pos, 300.f))
2007 					COMBINE=NULL;
2008 			}
2009 			else COMBINE=NULL;
2010 		}
2011 	}
2012 
2013 	if ((EERIEMouseButton & 1) && !(LastMouseClick & 1) && ((COMBINE !=NULL) || COMBINEGOLD))
2014 	{
2015 			ReleaseInfosCombine();
2016 
2017 		Entity * io;
2018 
2019 		if ((io=FlyingOverIO)!=NULL)
2020 		{
2021 			if (COMBINEGOLD)
2022 			{
2023 				char temp[256];
2024 				strcpy(temp,"gold_coin");
2025 				SendIOScriptEvent(io,SM_COMBINE,temp);
2026 			}
2027 			else
2028 			{
2029 				if (io!=COMBINE)
2030 				{
2031 					std::string temp = COMBINE->long_name();
2032 					EVENT_SENDER=COMBINE;
2033 
2034 					if(boost::starts_with(COMBINE->short_name(), "keyring")) {
2035 						ARX_KEYRING_Combine(io);
2036 					} else {
2037 						SendIOScriptEvent(io, SM_COMBINE, temp);
2038 					}
2039 				}
2040 			}
2041 		}
2042 
2043 		else // GLights
2044 		{
2045 			float fMaxdist = 300;
2046 
2047 			if (Project.telekinesis) fMaxdist = 850;
2048 
2049 			for(size_t i = 0; i < MAX_LIGHTS; i++) {
2050 				if ((GLight[i]!=NULL) &&
2051 					(GLight[i]->exist) &&
2052 					!fartherThan(GLight[i]->pos, player.pos, fMaxdist) &&
2053 					(!(GLight[i]->extras & EXTRAS_NO_IGNIT)))
2054 				{
2055 					if (MouseInRect(GLight[i]->mins.x, GLight[i]->mins.y, GLight[i]->maxs.x, GLight[i]->maxs.y))
2056 					{
2057 						if (COMBINE->ioflags & IO_ITEM)
2058 						{
2059 							if ((COMBINE == CURRENT_TORCH) || (COMBINE->_itemdata->LightValue == 1))
2060 							{
2061 								if (GLight[i]->status != 1)
2062 								{
2063 									GLight[i]->status = 1;
2064 									ARX_SOUND_PlaySFX(SND_TORCH_START, &GLight[i]->pos);
2065 								}
2066 							}
2067 
2068 							if (COMBINE->_itemdata->LightValue == 0)
2069 							{
2070 								if (GLight[i]->status != 0)
2071 								{
2072 									GLight[i]->status = 0;
2073 									ARX_SOUND_PlaySFX(SND_TORCH_END, &GLight[i]->pos);
2074 									SendIOScriptEvent(COMBINE, SM_CUSTOM, "douse");
2075 								}
2076 							}
2077 						}
2078 					}
2079 				}
2080 			}
2081 		}
2082 
2083 		COMBINEGOLD=0;
2084 		bool bQuitCombine = true;
2085 
2086 		if ((player.Interface & INTER_INVENTORY))
2087 		{
2088 			if (player.bag)
2089 			{
2090 
2091 					float fCenterX	= DANAECENTERX + INTERFACE_RATIO(-320 + 35) + INTERFACE_RATIO_DWORD(ITC.Get("hero_inventory")->m_dwWidth) - INTERFACE_RATIO(32 + 3) ;
2092 					float fSizY		= DANAESIZY - INTERFACE_RATIO(101) + INTERFACE_RATIO_LONG(InventoryY) + INTERFACE_RATIO(- 3 + 25) ;
2093 
2094 
2095 				float posx = ARX_CAST_TO_INT_THEN_FLOAT( fCenterX );
2096 				float posy = ARX_CAST_TO_INT_THEN_FLOAT( fSizY );
2097 
2098 				if (sActiveInventory > 0)
2099 				{
2100 					if (MouseInRect(posx, posy, posx+INTERFACE_RATIO(32), posy+INTERFACE_RATIO(32)))
2101 						bQuitCombine = false;
2102 				}
2103 
2104 				if (sActiveInventory < player.bag-1)
2105 				{
2106 
2107 					float fRatio	= INTERFACE_RATIO(32 + 5);
2108 
2109 					posy += checked_range_cast<int>(fRatio);
2110 
2111 					if (MouseInRect(posx, posy, posx+INTERFACE_RATIO(32), posy+INTERFACE_RATIO(32)))
2112 						bQuitCombine = false;
2113 				}
2114 			}
2115 		}
2116 
2117 		if (bQuitCombine)
2118 		{
2119 			COMBINE=NULL;
2120 			EERIEMouseButton &= ~1;
2121 		}
2122 	}
2123 
2124 		//lights
2125 	if (COMBINE)
2126 	{
2127 		float fMaxdist = 300;
2128 
2129 		if (Project.telekinesis) fMaxdist = 850;
2130 
2131 		for(size_t i = 0; i < MAX_LIGHTS; i++) {
2132 			if ((GLight[i]!=NULL) &&
2133 				(GLight[i]->exist) &&
2134 
2135 				!fartherThan(GLight[i]->pos, player.pos, fMaxdist) &&
2136 				(!(GLight[i]->extras & EXTRAS_NO_IGNIT)))
2137 			{
2138 				if (MouseInRect(GLight[i]->mins.x, GLight[i]->mins.y, GLight[i]->maxs.x, GLight[i]->maxs.y))
2139 				{
2140 					SpecialCursor = CURSOR_INTERACTION_ON;
2141 				}
2142 			}
2143 		}
2144 	}
2145 
2146 	// Double Clicked and not already combining.
2147 	if ((EERIEMouseButton & 4) && (COMBINE==NULL))
2148 	{
2149 		long accept_combine=1;
2150 
2151 		if ((SecondaryInventory!=NULL) && (InSecondaryInventoryPos(&DANAEMouse)))
2152 		{
2153 			Entity * io=(Entity *)SecondaryInventory->io;
2154 
2155 			if (io->ioflags & IO_SHOP) accept_combine=0;
2156 		}
2157 
2158 		if (accept_combine)
2159 		{
2160 
2161 			if ((FlyingOverIO) &&
2162 				( (FlyingOverIO->ioflags & IO_ITEM) && !(FlyingOverIO->ioflags & IO_MOVABLE)))
2163 			{
2164 				COMBINE=FlyingOverIO;
2165 				GetInfosCombine();
2166 				EERIEMouseButton&=~4;
2167 			}
2168 			else if (InInventoryPos(&DANAEMouse)) EERIEMouseButton&=4;
2169 		}
2170 	}
2171 
2172 	// Checks for Object Dragging
2173 	if (!EDITMODE)
2174 		if (( DRAGGING && !PLAYER_MOUSELOOK_ON &&
2175 			(!GInput->actionPressed(CONTROLS_CUST_MAGICMODE)) &&
2176 			(DRAGINTER==NULL)
2177 			)
2178 			|| // mode system shock
2179 			( DRAGGING && (config.input.autoReadyWeapon == false) &&
2180 			(!GInput->actionPressed(CONTROLS_CUST_MAGICMODE)) &&
2181 			(DRAGINTER==NULL))
2182 			)
2183 		{
2184 			if ( !TakeFromInventory(&STARTDRAG))
2185 			{
2186 				bool bOk = false;
2187 
2188 				Entity *io = InterClick(&STARTDRAG);
2189 
2190 				if (io && !BLOCK_PLAYER_CONTROLS)
2191 				{
2192 					if (ARX_MOUSE_OVER & ARX_MOUSE_OVER_BOOK)
2193 					{
2194 						if (io->show == SHOW_FLAG_ON_PLAYER)
2195 							bOk = true;
2196 					}
2197 					else
2198 					{
2199 						bOk = true;
2200 					}
2201 				}
2202 
2203 				if (bOk)
2204 				{
2205 					Set_DragInter(io);
2206 
2207 					if (io!=NULL)
2208 					{
2209 						ARX_PLAYER_Remove_Invisibility();
2210 
2211 						if (DRAGINTER->show==SHOW_FLAG_ON_PLAYER)
2212 						{
2213 							ARX_EQUIPMENT_UnEquip(entities.player(),DRAGINTER);
2214 							RemoveFromAllInventories(DRAGINTER);
2215 							DRAGINTER->bbox2.x=-1;
2216 									}
2217 
2218 						if (!EDITMODE)
2219 						{
2220 							if ((io->ioflags & IO_NPC) || (io->ioflags & IO_FIX))
2221 							{
2222 								Set_DragInter(NULL);
2223 								goto suivant;
2224 							}
2225 						}
2226 
2227 						if (io->ioflags & IO_UNDERWATER)
2228 						{
2229 							io->ioflags&=~IO_UNDERWATER;
2230 							ARX_SOUND_PlayInterface(SND_PLOUF, 0.8F + 0.4F * rnd());
2231 						}
2232 
2233 						DRAGINTER->show=SHOW_FLAG_NOT_DRAWN;
2234 						ARX_SOUND_PlayInterface(SND_INVSTD);
2235 					}
2236 				}
2237 				else
2238 					Set_DragInter(NULL);
2239 
2240 				suivant:
2241 					;
2242 			}
2243 			else ARX_PLAYER_Remove_Invisibility();
2244 		}
2245 
2246 	}
2247 
2248 	return false;
2249 }
2250 
2251 //-----------------------------------------------------------------------------
2252 // Switches from/to combat Mode i=-1 for switching from actual configuration
2253 // 2 to force Draw Weapon
2254 // 1 to force Combat Mode On
2255 // 0 to force Combat Mode Off
2256 //-----------------------------------------------------------------------------
ARX_INTERFACE_Combat_Mode(long i)2257 void ARX_INTERFACE_Combat_Mode(long i)
2258 {
2259 	if ( (i>=1) &&  (player.Interface & INTER_COMBATMODE) ) return;
2260 
2261 	if ( (i==0) &&  !(player.Interface & INTER_COMBATMODE) ) return;
2262 
2263 	if (EDITMODE) return;
2264 
2265 	if  ((player.Interface & INTER_COMBATMODE) && (entities.player()))
2266 	{
2267 		player.Interface&=~INTER_COMBATMODE;
2268 		player.Interface&=~INTER_NO_STRIKE;
2269 
2270 		ARX_EQUIPMENT_LaunchPlayerUnReadyWeapon();
2271 		long weapontype=ARX_EQUIPMENT_GetPlayerWeaponType();
2272 
2273 		if (entities.player() && arrowobj && (weapontype == WEAPON_BOW))
2274 		{
2275 			EERIE_LINKEDOBJ_UnLinkObjectFromObject(entities.player()->obj, arrowobj);
2276 		}
2277 
2278 		player.doingmagic=0;
2279 	}
2280 
2281 	else  if (((entities.player()->animlayer[1].cur_anim == NULL) || (entities.player()->animlayer[1].cur_anim == entities.player()->anims[ANIM_WAIT]))
2282 		&& (entities.player()))
2283 	{
2284 		ARX_INTERFACE_BookOpenClose(2);
2285 
2286 		player.Interface|=INTER_COMBATMODE;
2287 
2288 		if (i==2)
2289 		{
2290 			player.Interface|=INTER_NO_STRIKE;
2291 
2292 			if (config.input.mouseLookToggle)
2293 			{
2294 				TRUE_PLAYER_MOUSELOOK_ON = true;
2295 				SLID_START=float(arxtime);
2296 			}
2297 		}
2298 
2299 		ARX_EQUIPMENT_LaunchPlayerReadyWeapon();
2300 		player.doingmagic=0;
2301 	}
2302 }
2303 long CSEND=0;
2304 long MOVE_PRECEDENCE=0;
2305 
canOpenBookPage(ARX_INTERFACE_BOOK_MODE page)2306 static bool canOpenBookPage(ARX_INTERFACE_BOOK_MODE page) {
2307 	switch(page) {
2308 		case BOOKMODE_SPELLS:  return !!player.rune_flags;
2309 		default:               return true;
2310 	}
2311 }
2312 
openBookPage(ARX_INTERFACE_BOOK_MODE newPage,bool toggle=false)2313 static void openBookPage(ARX_INTERFACE_BOOK_MODE newPage, bool toggle = false) {
2314 
2315 	if((player.Interface & INTER_MAP) && Book_Mode == newPage) {
2316 
2317 		if(toggle) {
2318 			// Close the book
2319 			ARX_INTERFACE_BookOpenClose(2);
2320 		}
2321 
2322 		return; // nothing to do
2323 	}
2324 
2325 	if(!canOpenBookPage(newPage)) {
2326 		return;
2327 	}
2328 
2329 	if(player.Interface & INTER_MAP) {
2330 
2331 		onBookClosePage();
2332 
2333 		// If the book is already open, play the page turn sound
2334 		ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
2335 
2336 	} else {
2337 		// Otherwise open the book
2338 		ARX_INTERFACE_BookOpenClose(0);
2339 	}
2340 
2341 	Book_Mode = newPage;
2342 }
2343 
nextBookPage()2344 static ARX_INTERFACE_BOOK_MODE nextBookPage() {
2345 	ARX_INTERFACE_BOOK_MODE nextPage = Book_Mode, oldPage;
2346 	do {
2347 		oldPage = nextPage;
2348 
2349 		switch(oldPage) {
2350 			case BOOKMODE_STATS:   nextPage = BOOKMODE_SPELLS;  break;
2351 			case BOOKMODE_SPELLS:  nextPage = BOOKMODE_MINIMAP; break;
2352 			case BOOKMODE_MINIMAP: nextPage = BOOKMODE_QUESTS;  break;
2353 			case BOOKMODE_QUESTS:  nextPage = BOOKMODE_QUESTS;  break;
2354 		}
2355 
2356 		if(canOpenBookPage(nextPage)) {
2357 			return nextPage;
2358 		}
2359 
2360 	} while(nextPage != oldPage);
2361 	return Book_Mode;
2362 }
2363 
prevBookPage()2364 static ARX_INTERFACE_BOOK_MODE prevBookPage() {
2365 	ARX_INTERFACE_BOOK_MODE prevPage = Book_Mode, oldPage;
2366 	do {
2367 		oldPage = prevPage;
2368 
2369 		switch(oldPage) {
2370 			case BOOKMODE_STATS:   prevPage = BOOKMODE_STATS;   break;
2371 			case BOOKMODE_SPELLS:  prevPage = BOOKMODE_STATS;   break;
2372 			case BOOKMODE_MINIMAP: prevPage = BOOKMODE_SPELLS;  break;
2373 			case BOOKMODE_QUESTS:  prevPage = BOOKMODE_MINIMAP; break;
2374 		}
2375 
2376 		if(canOpenBookPage(prevPage)) {
2377 			return prevPage;
2378 		}
2379 
2380 	} while(prevPage != oldPage);
2381 	return Book_Mode;
2382 }
2383 
2384 extern unsigned long REQUEST_JUMP;
2385 //-----------------------------------------------------------------------------
ManagePlayerControls()2386 void ArxGame::ManagePlayerControls()
2387 {
2388 	if (((EERIEMouseButton & 4) && (!EDITMODE) && !(player.Interface & INTER_COMBATMODE))
2389 		&& (!player.doingmagic)
2390 		&& (!(ARX_MOUSE_OVER & ARX_MOUSE_OVER_BOOK))
2391 		&& (eMouseState != MOUSE_IN_NOTE)
2392 		)
2393 	{
2394 		Entity * t;
2395 
2396 		t=InterClick(&DANAEMouse);
2397 
2398 		if (t!=NULL)
2399 		{
2400 			if (t->ioflags & IO_NPC)
2401 			{
2402 				if (t->script.data!=NULL)
2403 				{
2404 					if (t->_npcdata->life>0.f)
2405 					{
2406 						SendIOScriptEvent(t,SM_CHAT);
2407 						EERIEMouseButton&=~4;
2408 
2409 						if (DRAGGING) DRAGGING = 0;
2410 					}
2411 					else
2412 					{
2413 						if (t->inventory!=NULL)
2414 						{
2415 							if (player.Interface & INTER_STEAL)
2416 								if (ioSteal && t != ioSteal)
2417 								{
2418 									SendIOScriptEvent(ioSteal, SM_STEAL,"off");
2419 									player.Interface &= ~INTER_STEAL;
2420 								}
2421 
2422 								ARX_INVENTORY_OpenClose(t);
2423 
2424 								if (player.Interface&(INTER_INVENTORY | INTER_INVENTORYALL))
2425 								{
2426 									ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
2427 								}
2428 
2429 								if (SecondaryInventory)
2430 								{
2431 									bForceEscapeFreeLook=true;
2432 									lOldTruePlayerMouseLook=!TRUE_PLAYER_MOUSELOOK_ON;
2433 								}
2434 						}
2435 					}
2436 				}
2437 			}
2438 			else
2439 			{
2440 				if (t->inventory!=NULL)
2441 				{
2442 					if (player.Interface & INTER_STEAL)
2443 					{
2444 						if (ioSteal && t != ioSteal)
2445 						{
2446 							SendIOScriptEvent(ioSteal, SM_STEAL,"off");
2447 							player.Interface &= ~INTER_STEAL;
2448 						}
2449 					}
2450 
2451 					ARX_INVENTORY_OpenClose(t);
2452 
2453 					if (SecondaryInventory)
2454 					{
2455 						bForceEscapeFreeLook=true;
2456 						lOldTruePlayerMouseLook=!TRUE_PLAYER_MOUSELOOK_ON;
2457 					}
2458 				}
2459 				else if (t->script.data!=NULL)
2460 				{
2461 					SendIOScriptEvent(t,SM_ACTION);
2462 				}
2463 
2464 				EERIEMouseButton&=~4;
2465 
2466 				if (DRAGGING) DRAGGING = 0;
2467 
2468 				EERIEMouseButton = 0;
2469 			}
2470 
2471 			EERIEMouseButton&=~4;
2472 			EERIEMouseButton = 0;
2473 		}
2474 	}
2475 
2476 	float MoveDiv;
2477 
2478 	Vec3f tm = Vec3f::ZERO;
2479 
2480 	// Checks STEALTH Key Status.
2481 	if (GInput->actionPressed(CONTROLS_CUST_STEALTHMODE) )
2482 	{
2483 		MoveDiv=0.02f;
2484 		player.Current_Movement|=PLAYER_MOVE_STEALTH;
2485 	}
2486 	else MoveDiv=0.0333333f;
2487 
2488 	{
2489 		long NOMOREMOVES=0;
2490 		float FD = 1.f;
2491 
2492 		if (eyeball.exist==2)
2493 		{
2494 			FD=18.f;
2495 			Vec3f old = eyeball.pos;
2496 
2497 			// Checks WALK_FORWARD Key Status.
2498 			if (GInput->actionPressed(CONTROLS_CUST_WALKFORWARD) )
2499 			{
2500 				float tr=radians(eyeball.angle.b);
2501 				eyeball.pos.x+=-(float)EEsin(tr)*20.f*(float)FD*0.033f;
2502 				eyeball.pos.z+=+(float)EEcos(tr)*20.f*(float)FD*0.033f;
2503 				NOMOREMOVES=1;
2504 			}
2505 
2506 			// Checks WALK_BACKWARD Key Status.
2507 			if (GInput->actionPressed(CONTROLS_CUST_WALKBACKWARD) )
2508 			{
2509 				float tr=radians(eyeball.angle.b);
2510 				eyeball.pos.x+=(float)EEsin(tr)*20.f*(float)FD*0.033f;
2511 				eyeball.pos.z+=-(float)EEcos(tr)*20.f*(float)FD*0.033f;
2512 				NOMOREMOVES=1;
2513 			}
2514 
2515 			// Checks STRAFE_LEFT Key Status.
2516 			if( (GInput->actionPressed(CONTROLS_CUST_STRAFELEFT)||
2517 				(GInput->actionPressed(CONTROLS_CUST_STRAFE)&&GInput->actionPressed(CONTROLS_CUST_TURNLEFT)))
2518 				&& !NOMOREMOVES)
2519 			{
2520 				float tr=radians(MAKEANGLE(eyeball.angle.b+90.f));
2521 				eyeball.pos.x+=-(float)EEsin(tr)*10.f*(float)FD*0.033f;
2522 				eyeball.pos.z+=+(float)EEcos(tr)*10.f*(float)FD*0.033f;
2523 				NOMOREMOVES=1;
2524 			}
2525 
2526 			// Checks STRAFE_RIGHT Key Status.
2527 			if( (GInput->actionPressed(CONTROLS_CUST_STRAFERIGHT)||
2528 				(GInput->actionPressed(CONTROLS_CUST_STRAFE)&&GInput->actionPressed(CONTROLS_CUST_TURNRIGHT)))
2529 				&& !NOMOREMOVES)
2530 			{
2531 				float tr=radians(MAKEANGLE(eyeball.angle.b-90.f));
2532 				eyeball.pos.x+=-(float)EEsin(tr)*10.f*(float)FD*0.033f;
2533 				//eyeball.pos.y+=FD*0.33f;
2534 				eyeball.pos.z+=(float)EEcos(tr)*10.f*(float)FD*0.033f;
2535 				NOMOREMOVES=1;
2536 			}
2537 
2538 			IO_PHYSICS phys;
2539 			phys.cyl.height=-110.f;
2540 			phys.cyl.origin.x=eyeball.pos.x;
2541 			phys.cyl.origin.y=eyeball.pos.y+70.f;
2542 			phys.cyl.origin.z=eyeball.pos.z;
2543 			phys.cyl.radius=45.f;
2544 
2545 			EERIE_CYLINDER test;
2546 			memcpy(&test,&phys.cyl,sizeof(EERIE_CYLINDER));
2547 			bool npc = AttemptValidCylinderPos(&test, NULL, CFLAG_JUST_TEST | CFLAG_NPC);
2548 			float val=CheckAnythingInCylinder(&phys.cyl,entities.player(),CFLAG_NO_NPC_COLLIDE | CFLAG_JUST_TEST);
2549 
2550 			if ((val > -40.f))
2551 			{
2552 				if (val <= 70.f)
2553 				{
2554 					eyeball.pos.y+=val-70.f;
2555 				}
2556 
2557 				if (!npc)
2558 				{
2559 					MagicSightFader+=framedelay*( 1.0f / 200 );
2560 
2561 					if (MagicSightFader>1.f) MagicSightFader=1.f;
2562 				}
2563 			}
2564 			else
2565 			{
2566 				eyeball.pos = old;
2567 			}
2568 		}
2569 
2570 		float t;
2571 		float multi;
2572 
2573 		if (EDITMODE || arxtime.is_paused()) FD=40.f;
2574 
2575 		bool left=GInput->actionPressed(CONTROLS_CUST_STRAFELEFT);
2576 
2577 		if(!left)
2578 		{
2579 			if(GInput->actionPressed(CONTROLS_CUST_STRAFE)&&GInput->actionPressed(CONTROLS_CUST_TURNLEFT))
2580 			{
2581 				left=true;
2582 			}
2583 		}
2584 
2585 		bool right=GInput->actionPressed(CONTROLS_CUST_STRAFERIGHT);
2586 
2587 		if(!right)
2588 		{
2589 			if(GInput->actionPressed(CONTROLS_CUST_STRAFE)&&GInput->actionPressed(CONTROLS_CUST_TURNRIGHT))
2590 			{
2591 				right=true;
2592 			}
2593 		}
2594 
2595 		// Checks WALK_BACKWARD Key Status.
2596 		if (	GInput->actionPressed(CONTROLS_CUST_WALKBACKWARD)
2597 			&&	!NOMOREMOVES	)
2598 		{
2599 			CurrFightPos=3;
2600 			multi = 1;
2601 
2602 			if (left || right)
2603 			{
2604 				multi = 0.8f;
2605 			}
2606 
2607 			t=radians(player.angle.b);
2608 			multi=5.f*(float)FD*MoveDiv*multi;
2609 			tm.x+=(float)EEsin(t)*multi;
2610 			tm.z-=(float)EEcos(t)*multi;
2611 
2612 			if(!USE_PLAYERCOLLISIONS)
2613 			{
2614 				t=radians(player.angle.a);
2615 				tm.y-=(float)EEsin(t)*multi;
2616 			}
2617 
2618 			player.Current_Movement|=PLAYER_MOVE_WALK_BACKWARD;
2619 
2620 			if (GInput->actionNowPressed(CONTROLS_CUST_WALKBACKWARD) )
2621 				MOVE_PRECEDENCE=PLAYER_MOVE_WALK_BACKWARD;
2622 		}
2623 		else if (MOVE_PRECEDENCE==PLAYER_MOVE_WALK_BACKWARD) MOVE_PRECEDENCE=0;
2624 
2625 		// Checks WALK_FORWARD Key Status.
2626 		if (GInput->actionPressed(CONTROLS_CUST_WALKFORWARD)
2627 			&& !NOMOREMOVES)
2628 		{
2629 			CurrFightPos=2;
2630 			multi = 1;
2631 
2632 			if (left || right)
2633 			{
2634 				multi=0.8f;
2635 			}
2636 
2637 			t=radians(player.angle.b);
2638 			multi=10.f*(float)FD*MoveDiv*multi;
2639 			tm.x-=(float)EEsin(t)*multi;
2640 			tm.z+=(float)EEcos(t)*multi;
2641 
2642 			if(!USE_PLAYERCOLLISIONS)
2643 			{
2644 				t=radians(player.angle.a);
2645 				tm.y+=(float)EEsin(t)*multi;
2646 			}
2647 
2648 			player.Current_Movement|=PLAYER_MOVE_WALK_FORWARD;
2649 
2650 			if (GInput->actionNowPressed(CONTROLS_CUST_WALKFORWARD) )
2651 				MOVE_PRECEDENCE=PLAYER_MOVE_WALK_FORWARD;
2652 		}
2653 		else if (MOVE_PRECEDENCE==PLAYER_MOVE_WALK_FORWARD) MOVE_PRECEDENCE=0;
2654 
2655 		// Checks STRAFE_LEFT Key Status.
2656 		if (left && !NOMOREMOVES)
2657 		{
2658 			CurrFightPos=0;
2659 			t=radians(MAKEANGLE(player.angle.b+90.f));
2660 			multi=6.f*(float)FD*MoveDiv;
2661 			tm.x-=(float)EEsin(t)*multi;
2662 			tm.z+=(float)EEcos(t)*multi;
2663 
2664 			player.Current_Movement|=PLAYER_MOVE_STRAFE_LEFT;
2665 
2666 			if (GInput->actionNowPressed(CONTROLS_CUST_STRAFELEFT) )
2667 				MOVE_PRECEDENCE=PLAYER_MOVE_STRAFE_LEFT;
2668 		}
2669 		else if (MOVE_PRECEDENCE==PLAYER_MOVE_STRAFE_LEFT) MOVE_PRECEDENCE=0;
2670 
2671 		// Checks STRAFE_RIGHT Key Status.
2672 		if ( right && !NOMOREMOVES)
2673 		{
2674 			CurrFightPos=1;
2675 			t=radians(MAKEANGLE(player.angle.b-90.f));
2676 			multi=6.f*(float)FD*MoveDiv;
2677 			tm.x-=(float)EEsin(t)*multi;
2678 			tm.z+=(float)EEcos(t)*multi;
2679 
2680 			player.Current_Movement|=PLAYER_MOVE_STRAFE_RIGHT;
2681 
2682 			if (GInput->actionNowPressed(CONTROLS_CUST_STRAFERIGHT) )
2683 				MOVE_PRECEDENCE=PLAYER_MOVE_STRAFE_RIGHT;
2684 		}
2685 		else if (MOVE_PRECEDENCE==PLAYER_MOVE_STRAFE_RIGHT) MOVE_PRECEDENCE=0;
2686 
2687 		moveto = player.pos + tm;
2688 	}
2689 
2690 	// Checks CROUCH Key Status.
2691 	if (GInput->actionNowPressed(CONTROLS_CUST_CROUCHTOGGLE))
2692 	{
2693 		bGCroucheToggle=!bGCroucheToggle;
2694 	}
2695 
2696 	if(	GInput->actionPressed(CONTROLS_CUST_CROUCH)||
2697 		bGCroucheToggle )
2698 	{
2699 		player.Current_Movement|=PLAYER_CROUCH;
2700 	}
2701 
2702 	if (GInput->actionNowPressed(CONTROLS_CUST_UNEQUIPWEAPON))
2703 	{
2704 		ARX_EQUIPMENT_UnEquipPlayerWeapon();
2705 	}
2706 
2707 	// Can only lean outside of combat mode
2708 	if (!(player.Interface & INTER_COMBATMODE))
2709 	{
2710 		// Checks LEAN_LEFT Key Status.
2711 		if (GInput->actionPressed(CONTROLS_CUST_LEANLEFT) )
2712 		{
2713 			player.Current_Movement|=PLAYER_LEAN_LEFT;
2714 		}
2715 
2716 		// Checks LEAN_RIGHT Key Status.
2717 		if (GInput->actionPressed(CONTROLS_CUST_LEANRIGHT) )
2718 		{
2719 			player.Current_Movement|=PLAYER_LEAN_RIGHT;
2720 		}
2721 	}
2722 
2723 	// Checks JUMP Key Status.
2724 	if(player.jumpphase == NotJumping && GInput->actionNowPressed(CONTROLS_CUST_JUMP)) {
2725 		REQUEST_JUMP = (unsigned long)(arxtime);
2726 	}
2727 
2728 	// MAGIC
2729 	if (GInput->actionPressed(CONTROLS_CUST_MAGICMODE))
2730 	{
2731 		if (!(player.Current_Movement & PLAYER_CROUCH) && (!BLOCK_PLAYER_CONTROLS)
2732 			&& (ARXmenu.currentmode==AMCM_OFF))
2733 		{
2734 			if (!ARX_SOUND_IsPlaying(SND_MAGIC_AMBIENT))
2735 				ARX_SOUND_PlaySFX(SND_MAGIC_AMBIENT, NULL, 1.0F, ARX_SOUND_PLAY_LOOPED);
2736 		}
2737 	}
2738 	else
2739 	{
2740 		ARX_SOUND_Stop(SND_MAGIC_AMBIENT);
2741 		ARX_SOUND_Stop(SND_MAGIC_DRAW);
2742 	}
2743 
2744 	if (GInput->actionNowPressed(CONTROLS_CUST_DRINKPOTIONLIFE))
2745 	{
2746 		SendInventoryObjectCommand("graph/obj3d/textures/item_potion_life", SM_INVENTORYUSE);
2747 	}
2748 
2749 	if (GInput->actionNowPressed(CONTROLS_CUST_DRINKPOTIONMANA))
2750 	{
2751 		SendInventoryObjectCommand("graph/obj3d/textures/item_potion_mana", SM_INVENTORYUSE);
2752 	}
2753 
2754 	if (GInput->actionNowPressed(CONTROLS_CUST_TORCH))
2755 	{
2756 		if (CURRENT_TORCH)
2757 		{
2758 			ARX_PLAYER_KillTorch();
2759 		}
2760 		else
2761 		{
2762 			Entity * io = ARX_INVENTORY_GetTorchLowestDurability();
2763 
2764 			if(io) {
2765 
2766 				Entity * ioo = io;
2767 
2768 				if(io->_itemdata->count > 1) {
2769 					ioo = CloneIOItem(io);
2770 					ioo->show = SHOW_FLAG_NOT_DRAWN;
2771 					ioo->scriptload = 1;
2772 					ioo->_itemdata->count = 1;
2773 					io->_itemdata->count--;
2774 				}
2775 
2776 				ARX_PLAYER_ClickedOnTorch(ioo);
2777 			}
2778 		}
2779 	}
2780 
2781 	if (GInput->actionNowPressed(CONTROLS_CUST_MINIMAP))
2782 	{
2783 		SHOW_INGAME_MINIMAP=!SHOW_INGAME_MINIMAP;
2784 	}
2785 
2786 	if (GInput->actionNowPressed(CONTROLS_CUST_PREVIOUS))
2787 	{
2788 		if (eMouseState == MOUSE_IN_BOOK)
2789 		{
2790 			if (player.Interface & INTER_MAP)
2791 			{
2792 				openBookPage(prevBookPage());
2793 			}
2794 		}
2795 		else if (InPlayerInventoryPos(&DANAEMouse))
2796 		{
2797 			if (!PLAYER_INTERFACE_HIDE_COUNT)
2798 			{
2799 				if ((player.Interface & INTER_INVENTORY))
2800 				{
2801 					if (player.bag)
2802 					{
2803 						if (sActiveInventory > 0)
2804 						{
2805 							ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
2806 							sActiveInventory --;
2807 						}
2808 					}
2809 				}
2810 			}
2811 		}
2812 		else if (player.Interface & INTER_MAP)
2813 		{
2814 			openBookPage(prevBookPage());
2815 		}
2816 		else
2817 		{
2818 			if (!PLAYER_INTERFACE_HIDE_COUNT)
2819 			{
2820 				if ((player.Interface & INTER_INVENTORY))
2821 				{
2822 					if (player.bag)
2823 					{
2824 						if (sActiveInventory > 0)
2825 						{
2826 							ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
2827 							sActiveInventory --;
2828 						}
2829 					}
2830 				}
2831 			}
2832 		}
2833 	}
2834 
2835 	if (GInput->actionNowPressed(CONTROLS_CUST_NEXT))
2836 	{
2837 		if (eMouseState == MOUSE_IN_BOOK)
2838 		{
2839 			if (player.Interface & INTER_MAP)
2840 			{
2841 				openBookPage(nextBookPage());
2842 			}
2843 		}
2844 		else if (InPlayerInventoryPos(&DANAEMouse))
2845 		{
2846 			if (!PLAYER_INTERFACE_HIDE_COUNT)
2847 			{
2848 				if ((player.Interface & INTER_INVENTORY))
2849 				{
2850 					if (player.bag)
2851 					{
2852 						if (sActiveInventory < player.bag - 1)
2853 						{
2854 							ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
2855 							sActiveInventory ++;
2856 						}
2857 					}
2858 				}
2859 			}
2860 		}
2861 		else if (player.Interface & INTER_MAP)
2862 		{
2863 			openBookPage(nextBookPage());
2864 		}
2865 		else
2866 		{
2867 			if (!PLAYER_INTERFACE_HIDE_COUNT)
2868 			{
2869 				if ((player.Interface & INTER_INVENTORY))
2870 				{
2871 					if (player.bag)
2872 					{
2873 						if (sActiveInventory < player.bag - 1)
2874 						{
2875 							ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
2876 							sActiveInventory ++;
2877 						}
2878 					}
2879 				}
2880 			}
2881 		}
2882 	}
2883 
2884 	if(GInput->actionNowPressed(CONTROLS_CUST_BOOKCHARSHEET)) {
2885 		openBookPage(BOOKMODE_STATS, true);
2886 	}
2887 
2888 	if(GInput->actionNowPressed(CONTROLS_CUST_BOOKSPELL) && player.rune_flags) {
2889 		openBookPage(BOOKMODE_SPELLS, true);
2890 	}
2891 
2892 	if(GInput->actionNowPressed(CONTROLS_CUST_BOOKMAP)) {
2893 		openBookPage(BOOKMODE_MINIMAP, true);
2894 	}
2895 
2896 	if(GInput->actionNowPressed(CONTROLS_CUST_BOOKQUEST)) {
2897 		openBookPage(BOOKMODE_QUESTS, true);
2898 	}
2899 
2900 	if (GInput->actionNowPressed(CONTROLS_CUST_CANCELCURSPELL))
2901 	{
2902 		for (long i=MAX_SPELLS-1;i>=0;i--)
2903 		{
2904 			if ((spells[i].exist) && (spells[i].caster==0))
2905 				if (spellicons[spells[i].type].bDuration)
2906 				{
2907 					ARX_SPELLS_AbortSpellSound();
2908 					spells[i].tolive=0;
2909 					break;
2910 				}
2911 		}
2912 	}
2913 
2914 	if (GInput->actionNowPressed(CONTROLS_CUST_PRECAST1))
2915 	{
2916 		if (((player.Interface & INTER_COMBATMODE) && !bIsAiming) || !player.doingmagic)
2917 			if (Precast[0].typ != -1)
2918 				ARX_SPELLS_Precast_Launch(0);
2919 	}
2920 
2921 	if (GInput->actionNowPressed(CONTROLS_CUST_PRECAST2))
2922 	{
2923 		if (((player.Interface & INTER_COMBATMODE) && !bIsAiming) || !player.doingmagic)
2924 			if (Precast[1].typ != -1)
2925 				ARX_SPELLS_Precast_Launch(1);
2926 	}
2927 
2928 	if (GInput->actionNowPressed(CONTROLS_CUST_PRECAST3))
2929 	{
2930 		if (((player.Interface & INTER_COMBATMODE) && !bIsAiming) || !player.doingmagic)
2931 			if (Precast[2].typ != -1)
2932 				ARX_SPELLS_Precast_Launch(2);
2933 	}
2934 
2935 	if (GInput->actionNowPressed(CONTROLS_CUST_WEAPON)||lChangeWeapon)
2936 	{
2937 		bool bGo = true;
2938 
2939 		if (lChangeWeapon > 0)
2940 		{
2941 			if (lChangeWeapon == 2)
2942 			{
2943 				lChangeWeapon--;
2944 			}
2945 			else
2946 			{
2947 				if(	(entities.player()->animlayer[1].cur_anim==NULL)||
2948 					(entities.player()->animlayer[1].cur_anim == entities.player()->anims[ANIM_WAIT]))
2949 				{
2950 					lChangeWeapon--;
2951 
2952 					if (pIOChangeWeapon)
2953 					{
2954 						SendIOScriptEvent(pIOChangeWeapon,SM_INVENTORYUSE,"");
2955 						pIOChangeWeapon=NULL;
2956 					}
2957 				}
2958 				else
2959 				{
2960 					bGo=false;
2961 				}
2962 			}
2963 		}
2964 
2965 		if (bGo)
2966 		{
2967 			if (player.Interface & INTER_COMBATMODE)
2968 			{
2969 				ARX_INTERFACE_Combat_Mode(0);
2970 				bGToggleCombatModeWithKey=false;
2971 				SPECIAL_DRAW_WEAPON=0;
2972 
2973 				if (config.input.mouseLookToggle)
2974 					TRUE_PLAYER_MOUSELOOK_ON=MEMO_PLAYER_MOUSELOOK_ON;
2975 			}
2976 			else
2977 			{
2978 				MEMO_PLAYER_MOUSELOOK_ON=TRUE_PLAYER_MOUSELOOK_ON;
2979 				SPECIAL_DRAW_WEAPON=1;
2980 				TRUE_PLAYER_MOUSELOOK_ON = true;
2981 				SLID_START=float(arxtime);
2982 				ARX_INTERFACE_Combat_Mode(2);
2983 				bGToggleCombatModeWithKey=true;
2984 
2985 			}
2986 		}
2987 	}
2988 
2989 	if(EERIEMouseButton&1) bGToggleCombatModeWithKey=false;
2990 
2991 	if(bForceEscapeFreeLook)
2992 	{
2993 		TRUE_PLAYER_MOUSELOOK_ON = false;
2994 
2995 		if (!GInput->actionPressed(CONTROLS_CUST_FREELOOK))
2996 		{
2997 			bForceEscapeFreeLook=false;
2998 		}
2999 	}
3000 	else
3001 	{
3002 		if(eMouseState!=MOUSE_IN_INVENTORY_ICON)
3003 		{
3004 			if (!config.input.mouseLookToggle)
3005 			{
3006 				if (GInput->actionPressed(CONTROLS_CUST_FREELOOK))
3007 				{
3008 					if (!TRUE_PLAYER_MOUSELOOK_ON)
3009 					{
3010 						TRUE_PLAYER_MOUSELOOK_ON = true;
3011 						SLID_START=float(arxtime);
3012 					}
3013 				}
3014 				else
3015 				{
3016 					TRUE_PLAYER_MOUSELOOK_ON = false;
3017 				}
3018 			}
3019 			else
3020 			{
3021 				if (GInput->actionNowPressed(CONTROLS_CUST_FREELOOK))
3022 				{
3023 					if (!TRUE_PLAYER_MOUSELOOK_ON)
3024 					{
3025 						TRUE_PLAYER_MOUSELOOK_ON = true;
3026 						SLID_START=float(arxtime);
3027 					}
3028 					else
3029 					{
3030 						TRUE_PLAYER_MOUSELOOK_ON = false;
3031 
3032 						if (player.Interface & INTER_COMBATMODE)
3033 							ARX_INTERFACE_Combat_Mode(0);
3034 					}
3035 				}
3036 			}
3037 		}
3038 	}
3039 
3040 
3041 	if(	(player.Interface&INTER_COMBATMODE)&&
3042 		(GInput->actionNowReleased(CONTROLS_CUST_FREELOOK)) )
3043 	{
3044 		ARX_INTERFACE_Combat_Mode(0);
3045 	}
3046 
3047 	if (EDITMODE) return;//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3048 
3049 	// Checks INVENTORY Key Status.
3050 	if (GInput->actionNowPressed(CONTROLS_CUST_INVENTORY))
3051 	{
3052 		if (player.Interface & INTER_COMBATMODE)
3053 		{
3054 			ARX_INTERFACE_Combat_Mode(0);
3055 		}
3056 
3057 		bInverseInventory=!bInverseInventory;
3058 		lOldTruePlayerMouseLook=TRUE_PLAYER_MOUSELOOK_ON;
3059 
3060 		if (!config.input.mouseLookToggle)
3061 		{
3062 			bForceEscapeFreeLook=true;
3063 		}
3064 	}
3065 
3066 	// Checks BOOK Key Status.
3067 	if (GInput->actionNowPressed(CONTROLS_CUST_BOOK))
3068 		ARX_INTERFACE_BookOpenClose(0);
3069 
3070 	//	Check For Combat Mode ON/OFF
3071 	if (	(EERIEMouseButton & 1)
3072 #ifdef BUILD_EDITOR
3073 		&&	(EDITION==EDITION_IO)
3074 #endif
3075 		&&	(!(player.Interface & INTER_COMBATMODE))
3076 		&&	(!(ARX_MOUSE_OVER & ARX_MOUSE_OVER_BOOK))
3077 		&&	(!EDITMODE)
3078 		&&	(!SpecialCursor)
3079 		&&  (PLAYER_MOUSELOOK_ON)
3080 		&&	(DRAGINTER==NULL)
3081 		&&	(!InInventoryPos(&DANAEMouse)
3082 		&& (config.input.autoReadyWeapon))
3083 		)
3084 	{
3085 		if (!(LastMouseClick & 1))
3086 		{
3087 			COMBAT_MODE_ON_START_TIME = (unsigned long)(arxtime);
3088 		}
3089 		else
3090 		{
3091 			if (float(arxtime) - COMBAT_MODE_ON_START_TIME>10)
3092 			{
3093 				ARX_INTERFACE_Combat_Mode(1);
3094 
3095 				if (! config.input.autoReadyWeapon)
3096 					bGToggleCombatModeWithKey=true;
3097 			}
3098 		}
3099 	}
3100 
3101 	if	(lOldTruePlayerMouseLook!=TRUE_PLAYER_MOUSELOOK_ON)
3102 	{
3103 		bInverseInventory=false;
3104 
3105 		if (TRUE_PLAYER_MOUSELOOK_ON)
3106 		{
3107 			if (!CSEND)
3108 			{
3109 				CSEND=1;
3110 				SendIOScriptEvent(entities.player(),SM_EXPLORATIONMODE);
3111 			}
3112 		}
3113 	}
3114 	else
3115 	{
3116 		if (CSEND)
3117 		{
3118 			CSEND=0;
3119 			SendIOScriptEvent(entities.player(),SM_CURSORMODE);
3120 		}
3121 	}
3122 
3123 	static long lOldInterfaceTemp=0;
3124 
3125 	if (TRUE_PLAYER_MOUSELOOK_ON)
3126 	{
3127 		if(bInverseInventory)
3128 		{
3129 			bRenderInCursorMode=true;
3130 
3131 			if(MAGICMODE<0)
3132 			{
3133 				InventoryOpenClose(1);
3134 			}
3135 		}
3136 		else
3137 		{
3138 			if(!bInventoryClosing)
3139 			{
3140 
3141 				lTimeToDrawMecanismCursor=0;
3142 				lNbToDrawMecanismCursor=0;
3143 
3144 				if (player.Interface & INTER_INVENTORYALL)
3145 				{
3146 					ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
3147 					bInventoryClosing = true;
3148 					lOldInterfaceTemp=INTER_INVENTORYALL;
3149 				}
3150 
3151 
3152 				bRenderInCursorMode=false;
3153 				InventoryOpenClose(2);
3154 
3155 				if((player.Interface &INTER_INVENTORY))
3156 				{
3157 					Entity * io = NULL;
3158 
3159 					if (SecondaryInventory!=NULL)
3160 					{
3161 						io = (Entity *)SecondaryInventory->io;
3162 					}
3163 					else if (player.Interface & INTER_STEAL)
3164 					{
3165 						io = ioSteal;
3166 					}
3167 
3168 					if (io!=NULL)
3169 					{
3170 						InventoryDir=-1;
3171 						SendIOScriptEvent(io,SM_INVENTORY2_CLOSE);
3172 						TSecondaryInventory=SecondaryInventory;
3173 						SecondaryInventory=NULL;
3174 					}
3175 				}
3176 
3177 				if(config.input.mouseLookToggle)
3178 				{
3179 					TRUE_PLAYER_MOUSELOOK_ON = true;
3180 					SLID_START=float(arxtime);
3181 				}
3182 			}
3183 		}
3184 	}
3185 	else
3186 	{
3187 		if(bInverseInventory)
3188 		{
3189 			if(!bInventoryClosing)
3190 			{
3191 
3192 				bRenderInCursorMode=false;
3193 
3194 				InventoryOpenClose(2);
3195 
3196 				if((player.Interface &INTER_INVENTORY))
3197 				{
3198 					Entity * io = NULL;
3199 
3200 					if (SecondaryInventory!=NULL)
3201 					{
3202 						io = (Entity *)SecondaryInventory->io;
3203 					}
3204 					else if (player.Interface & INTER_STEAL)
3205 					{
3206 						io = ioSteal;
3207 					}
3208 
3209 					if (io!=NULL)
3210 					{
3211 						InventoryDir=-1;
3212 						SendIOScriptEvent(io,SM_INVENTORY2_CLOSE);
3213 						TSecondaryInventory=SecondaryInventory;
3214 						SecondaryInventory=NULL;
3215 					}
3216 				}
3217 
3218 				if(config.input.mouseLookToggle)
3219 				{
3220 					TRUE_PLAYER_MOUSELOOK_ON = true;
3221 					SLID_START=float(arxtime);
3222 				}
3223 			}
3224 		}
3225 		else
3226 		{
3227 
3228 			bRenderInCursorMode=true;
3229 
3230 			if(MAGICMODE<0)
3231 			{
3232 
3233 				if(lOldInterfaceTemp)
3234 				{
3235 					lOldInterface=lOldInterfaceTemp;
3236 					lOldInterfaceTemp=0;
3237 					ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
3238 				}
3239 
3240 				if(lOldInterface)
3241 				{
3242 					player.Interface|=lOldInterface;
3243 					player.Interface&=~INTER_INVENTORY;
3244 				}
3245 				else
3246 					InventoryOpenClose(1);
3247 			}
3248 		}
3249 
3250 		if (bRenderInCursorMode)
3251 		{
3252 			if (eyeball.exist != 0)
3253 			{
3254 				long lNumSpell=ARX_SPELLS_GetInstance(SPELL_FLYING_EYE);
3255 
3256 				if (lNumSpell >= 0)
3257 				{
3258 					ARX_SPELLS_Kill(lNumSpell);
3259 				}
3260 			}
3261 		}
3262 	}
3263 }
3264 
3265 //-----------------------------------------------------------------------------
ARX_INTERFACE_Reset()3266 void ARX_INTERFACE_Reset()
3267 {
3268 	SMOOTHSLID=0;
3269 	PLAYER_INTERFACE_HIDE_COUNT=0;
3270 	BLOCK_PLAYER_CONTROLS=0;
3271 	SLID_VALUE=0;
3272 	CINEMASCOPE=0;
3273 	CINEMA_INC=0;
3274 	CINEMA_DECAL=0;
3275 }
3276 
3277 //-----------------------------------------------------------------------------
ARX_INTERFACE_SetCinemascope(long status,long smooth)3278 void ARX_INTERFACE_SetCinemascope(long status,long smooth)
3279 {
3280 	if (status)
3281 	{
3282 		CINEMASCOPE=1;//++;
3283 		g_TimeStartCinemascope = arxtime.get_updated();
3284 	}
3285 	else
3286 	{
3287 		CINEMASCOPE=0;//--;
3288 		g_TimeStartCinemascope = 0;
3289 	}
3290 
3291 	arx_assert(CINEMASCOPE >= 0);
3292 
3293 	if (CINEMASCOPE)
3294 	{
3295 		if (smooth)
3296 		{
3297 			CINEMA_INC=1;
3298 		}
3299 		else CINEMA_DECAL=100;
3300 	}
3301 	else
3302 	{
3303 		if (smooth)
3304 		{
3305 			CINEMA_INC=-1;
3306 		}
3307 		else CINEMA_DECAL=0;
3308 	}
3309 
3310 	if (player.Interface & INTER_INVENTORY)
3311 	{
3312 		player.Interface &=~ INTER_INVENTORY;
3313 	}
3314 
3315 	if (player.Interface & INTER_INVENTORYALL)
3316 	{
3317 		player.Interface &=~ INTER_INVENTORYALL;
3318 	}
3319 }
3320 
3321 //-----------------------------------------------------------------------------
ARX_INTERFACE_PlayerInterfaceModify(long showhide,long smooth)3322 void ARX_INTERFACE_PlayerInterfaceModify(long showhide,long smooth)
3323 {
3324 	if (showhide == 0)
3325 	{
3326 		InventoryOpenClose(2);
3327 		ARX_INTERFACE_BookOpenClose(2);
3328 		ARX_INTERFACE_NoteClose();
3329 	}
3330 
3331 	if (showhide) PLAYER_INTERFACE_HIDE_COUNT = 0;
3332 	else PLAYER_INTERFACE_HIDE_COUNT = 1;
3333 
3334 	if (PLAYER_INTERFACE_HIDE_COUNT<0)
3335 		PLAYER_INTERFACE_HIDE_COUNT=0;
3336 
3337 	if (smooth)
3338 	{
3339 		if (showhide) SMOOTHSLID=-1;
3340 		else SMOOTHSLID=1;
3341 	}
3342 	else
3343 	{
3344 		if (showhide) SLID_VALUE=0.f;
3345 		else SLID_VALUE=100.f;
3346 
3347 		lSLID_VALUE = SLID_VALUE;
3348 	}
3349 }
3350 
ManageKeyMouse()3351 void ArxGame::ManageKeyMouse() {
3352 
3353 	if (ARXmenu.currentmode == AMCM_OFF)
3354 	{
3355 		Entity * pIO = NULL;
3356 
3357 		if (!BLOCK_PLAYER_CONTROLS)
3358 		{
3359 			if (TRUE_PLAYER_MOUSELOOK_ON && !(player.Interface & INTER_COMBATMODE)
3360 				&& (eMouseState != MOUSE_IN_NOTE)
3361 				)
3362 			{
3363 				Vec2s poss = MemoMouse;
3364 
3365 				// mode systemshock
3366 				if (config.input.mouseLookToggle && config.input.autoReadyWeapon == false)
3367 				{
3368 
3369 					float fX =  DANAESIZX * 0.5f;
3370 					float fY =	DANAESIZY * 0.5f;
3371 					DANAEMouse.x = checked_range_cast<short>(fX);
3372 					DANAEMouse.y = checked_range_cast<short>(fY);
3373 
3374 					pIO = FlyingOverObject(&DANAEMouse);
3375 					if(pIO) {
3376 						FlyingOverIO = pIO;
3377 						MemoMouse = DANAEMouse;
3378 					}
3379 				}
3380 				else
3381 					pIO = FlyingOverObject(&poss);
3382 			}
3383 			else
3384 				pIO = FlyingOverObject(&DANAEMouse);
3385 		}
3386 
3387 		if (pIO && (ARX_MOUSE_OVER & ARX_MOUSE_OVER_BOOK))
3388 		{
3389 			for (long i=0;i<MAX_EQUIPED;i++)
3390 			{
3391 				if ((player.equiped[i]!=0)
3392 					&&	ValidIONum(player.equiped[i])
3393 					&&	(entities[player.equiped[i]] == pIO))
3394 					FlyingOverIO = pIO;
3395 			}
3396 		}
3397 
3398 		if ((pIO)
3399 			&& (pIO->gameFlags & GFLAG_INTERACTIVITY)
3400 			&& !(ARX_MOUSE_OVER & ARX_MOUSE_OVER_BOOK)
3401 			&& (eMouseState != MOUSE_IN_NOTE)
3402 			)
3403 		{
3404 			if (!(EERIEMouseButton & 2) && (LastMouseClick & 2)
3405 				&&  (STARTED_ACTION_ON_IO == pIO))
3406 			{
3407 				if (pIO->ioflags & IO_ITEM)
3408 				{
3409 					FlyingOverIO = pIO;
3410 					COMBINE=NULL;
3411 
3412 					if (DRAGINTER == NULL)
3413 					{
3414 						bool bOk = true;
3415 
3416 						if (SecondaryInventory!=NULL)
3417 						{
3418 							Entity * temp=(Entity *)SecondaryInventory->io;
3419 
3420 							if (IsInSecondaryInventory(FlyingOverIO))
3421 								if (temp->ioflags & IO_SHOP)
3422 									bOk = false;
3423 						}
3424 
3425 							Entity * io=entities.player();
3426 							ANIM_USE * useanim=&io->animlayer[1];
3427 							long type=ARX_EQUIPMENT_GetPlayerWeaponType();
3428 
3429 							switch (type)
3430 							{
3431 							case WEAPON_DAGGER:
3432 
3433 								if(useanim->cur_anim==io->anims[ANIM_DAGGER_UNREADY_PART_1]) bOk=false;
3434 
3435 								break;
3436 							case WEAPON_1H:
3437 
3438 								if(useanim->cur_anim==io->anims[ANIM_1H_UNREADY_PART_1]) bOk=false;
3439 
3440 								break;
3441 							case WEAPON_2H:
3442 
3443 								if(useanim->cur_anim==io->anims[ANIM_2H_UNREADY_PART_1]) bOk=false;
3444 
3445 								break;
3446 							case WEAPON_BOW:
3447 
3448 								if(useanim->cur_anim==io->anims[ANIM_MISSILE_UNREADY_PART_1]) bOk=false;
3449 
3450 								break;
3451 							default:
3452 								break;
3453 							}
3454 
3455 						if (bOk)
3456 						{
3457 							if (!((FlyingOverIO->_itemdata->playerstacksize <= 1) && (FlyingOverIO->_itemdata->count > 1)))
3458 							{
3459 								SendIOScriptEvent(FlyingOverIO,SM_INVENTORYUSE);
3460 
3461 								if (!((config.input.autoReadyWeapon == false) && (config.input.mouseLookToggle)))
3462 								{
3463 									TRUE_PLAYER_MOUSELOOK_ON = false;
3464 								}
3465 							}
3466 						}
3467 					}
3468 
3469 					if ((config.input.autoReadyWeapon == false) && (config.input.mouseLookToggle))
3470 					{
3471 						EERIEMouseButton &= ~2;
3472 					}
3473 				}
3474 				}
3475 			else //!TRUE_PLAYER_MOUSELOOK_ON
3476 			{
3477 				if ((EERIEMouseButton & 2) && !(LastMouseClick & 2))
3478 				{
3479 					STARTED_ACTION_ON_IO=FlyingOverIO;
3480 				}
3481 			}
3482 		}
3483 
3484 		if ((eMouseState == MOUSE_IN_WORLD) ||
3485 			((eMouseState == MOUSE_IN_BOOK) && (!((ARX_MOUSE_OVER & ARX_MOUSE_OVER_BOOK) && (Book_Mode != BOOKMODE_MINIMAP))))
3486 			)
3487 		{
3488 			if (config.input.mouseLookToggle)
3489 			{
3490 				if (eMouseState != MOUSE_IN_NOTE)
3491 				{
3492 					if ((EERIEMouseButton & 2) && !(LastMouseClick & 2)&&(config.input.linkMouseLookToUse))
3493 					{
3494 						if (!(FlyingOverIO && (FlyingOverIO->ioflags & IO_ITEM)) || DRAGINTER)
3495 						{
3496 							if (!TRUE_PLAYER_MOUSELOOK_ON)
3497 							{
3498 								if (!InInventoryPos(&DANAEMouse))
3499 								{
3500 									if (!((player.Interface & INTER_MAP) && Book_Mode != BOOKMODE_MINIMAP))
3501 									{
3502 										TRUE_PLAYER_MOUSELOOK_ON = true;
3503 										EERIEMouseButton &= ~2;
3504 										SLID_START = float(arxtime);
3505 									}
3506 								}
3507 							}
3508 							else
3509 							{
3510 								if (!((config.input.autoReadyWeapon == false) && (config.input.mouseLookToggle) && FlyingOverIO && (FlyingOverIO->ioflags & IO_ITEM)))
3511 								{
3512 									TRUE_PLAYER_MOUSELOOK_ON = false;
3513 									if (player.Interface & INTER_COMBATMODE && !(player.Interface & INTER_NOTE))
3514 										ARX_INTERFACE_Combat_Mode(0);
3515 								}
3516 							}
3517 						}
3518 					}
3519 				}
3520 			}
3521 			else
3522 			{
3523 				if (eMouseState != MOUSE_IN_NOTE)
3524 				{
3525 					if(	(EERIEMouseButton & 2) &&
3526 						(!(ARX_MOUSE_OVER & ARX_MOUSE_OVER_BOOK & (Book_Mode != BOOKMODE_MINIMAP))) &&
3527 						(!TRUE_PLAYER_MOUSELOOK_ON || SPECIAL_DRAW_WEAPON)&&
3528 					        (config.input.linkMouseLookToUse))
3529 					{
3530 						if (SPECIAL_DRAW_WEAPON)
3531 							SPECIAL_DRAW_WEAPON=0;
3532 						else if (!InInventoryPos(&DANAEMouse))
3533 						{
3534 							if (SPECIAL_DRAW_WEAPON)
3535 							{
3536 								TRUE_PLAYER_MOUSELOOK_ON = false;
3537 								SPECIAL_DRAW_WEAPON=0;
3538 							}
3539 							else
3540 							{
3541 								TRUE_PLAYER_MOUSELOOK_ON = true;
3542 								SLID_START = float(arxtime);
3543 							}
3544 						}
3545 					}
3546 					else if ((!(EERIEMouseButton & 2)) && config.input.linkMouseLookToUse && (LastMouseClick & 2))
3547 					{
3548 						if (!SPECIAL_DRAW_WEAPON)
3549 						{
3550 							if (!GInput->actionPressed(CONTROLS_CUST_FREELOOK))
3551 								TRUE_PLAYER_MOUSELOOK_ON = false;
3552 
3553 							if ((player.Interface & INTER_COMBATMODE) && !GInput->actionPressed(CONTROLS_CUST_FREELOOK))
3554 								ARX_INTERFACE_Combat_Mode(0);
3555 						}
3556 
3557 						EERIEMouseButton &= ~2;
3558 					}
3559 				}
3560 
3561 				if (TRUE_PLAYER_MOUSELOOK_ON && (!(EERIEMouseButton & 2)) && !SPECIAL_DRAW_WEAPON)
3562 				{
3563 					if (!GInput->actionPressed(CONTROLS_CUST_FREELOOK))
3564 						TRUE_PLAYER_MOUSELOOK_ON = false;
3565 				}
3566 			}
3567 		}
3568 
3569 		PLAYER_MOUSELOOK_ON=TRUE_PLAYER_MOUSELOOK_ON;
3570 
3571 		if ((player.doingmagic==2)&& (config.input.mouseLookToggle))
3572 			PLAYER_MOUSELOOK_ON = false;
3573 	}
3574 
3575 	if(ARXmenu.currentmode!=AMCM_OFF)
3576 	{
3577 		PLAYER_MOUSELOOK_ON = false;
3578 	}
3579 
3580 	// Checks For MouseGrabbing/Restoration after Grab
3581 	bool bRestoreCoordMouse=true;
3582 
3583 	if(PLAYER_MOUSELOOK_ON && !LAST_PLAYER_MOUSELOOK_ON) {
3584 
3585 		MemoMouse = DANAEMouse;
3586 		EERIEMouseGrab = 1;
3587 
3588 	} else if(!PLAYER_MOUSELOOK_ON && LAST_PLAYER_MOUSELOOK_ON) {
3589 
3590 		EERIEMouseGrab = 0;
3591 		DANAEMouse = MemoMouse;
3592 
3593 		if(mainApp->GetWindow()->isFullScreen()) {
3594 			GInput->setMousePosAbs(DANAEMouse);
3595 		}
3596 
3597 		bRestoreCoordMouse=false;
3598 	}
3599 
3600 	LAST_PLAYER_MOUSELOOK_ON=PLAYER_MOUSELOOK_ON;
3601 	PLAYER_ROTATION=0;
3602 
3603 	long mouseDiffX = GInput->getMousePosRel().x;
3604 	long mouseDiffY = GInput->getMousePosRel().y;
3605 
3606 	ARX_Menu_Manage();
3607 
3608 	if(bRestoreCoordMouse) {
3609 		DANAEMouse=GInput->getMousePosAbs();
3610 	}
3611 
3612 	// Player/Eyeball Freelook Management
3613 	if(!BLOCK_PLAYER_CONTROLS) {
3614 
3615 		GetInventoryObj_INVENTORYUSE(&DANAEMouse);
3616 
3617 		static int flPushTimeX[2] = { 0, 0 };
3618 		static int flPushTimeY[2] = { 0, 0 };
3619 		bool bKeySpecialMove=false;
3620 
3621 		if(!GInput->actionPressed(CONTROLS_CUST_STRAFE)) {
3622 			float fTime = arxtime.get_updated();
3623 			int iTime = checked_range_cast<int>(fTime);
3624 			if(GInput->actionPressed(CONTROLS_CUST_TURNLEFT)) {
3625 				if(!flPushTimeX[0]) {
3626 					flPushTimeX[0] = iTime;
3627 				}
3628 				bKeySpecialMove = true;
3629 			} else {
3630 				flPushTimeX[0] = 0;
3631 			}
3632 			if(GInput->actionPressed(CONTROLS_CUST_TURNRIGHT)) {
3633 				if(!flPushTimeX[1]) {
3634 					flPushTimeX[1] = iTime;
3635 				}
3636 				bKeySpecialMove = true;
3637 			} else {
3638 				flPushTimeX[1] = 0;
3639 			}
3640 		}
3641 
3642 		if(USE_PLAYERCOLLISIONS) {
3643 			float fTime = arxtime.get_updated();
3644 			int iTime = checked_range_cast<int>(fTime);
3645 			if(GInput->actionPressed(CONTROLS_CUST_LOOKUP)) {
3646 				if(!flPushTimeY[0]) {
3647 					flPushTimeY[0] = iTime;
3648 				}
3649 				bKeySpecialMove = true;
3650 			} else {
3651 				flPushTimeY[0] = 0;
3652 			}
3653 			if(GInput->actionPressed(CONTROLS_CUST_LOOKDOWN)) {
3654 				if(!flPushTimeY[1]) {
3655 					flPushTimeY[1] = iTime;
3656 				}
3657 				bKeySpecialMove = true;
3658 			} else {
3659 				flPushTimeY[1] = 0;
3660 			}
3661 		}
3662 
3663 		if(bKeySpecialMove) {
3664 
3665 			int iAction = 0;
3666 			if(flPushTimeX[0] || flPushTimeX[1]) {
3667 				if(flPushTimeX[0] < flPushTimeX[1]) {
3668 					mouseDiffX = 10;
3669 				} else {
3670 					mouseDiffX = -10;
3671 				}
3672 				iAction |= 1;
3673 			}
3674 			if(flPushTimeY[0] || flPushTimeY[1]) {
3675 				if(flPushTimeY[0] < flPushTimeY[1]) {
3676 					mouseDiffY = 10;
3677 				} else {
3678 					mouseDiffY = -10;
3679 				}
3680 				iAction |= 2;
3681 			}
3682 			if(!(iAction & 1)) {
3683 				mouseDiffX = 0;
3684 			}
3685 			if(!(iAction & 2)) {
3686 				mouseDiffY = 0;
3687 			}
3688 
3689 		} else {
3690 
3691 			if(bRenderInCursorMode) {
3692 				Vec2s mousePosRel = GInput->getMousePosRel();
3693 				if(DANAEMouse.x == DANAESIZX - 1 && mousePosRel.x > 8) {
3694 					mouseDiffY = 0;
3695 					mouseDiffX = mousePosRel.x;
3696 					bKeySpecialMove = true;
3697 				} else if(DANAEMouse.x == 0 && mousePosRel.x < -8) {
3698 					mouseDiffY = 0;
3699 					mouseDiffX = mousePosRel.x;
3700 					bKeySpecialMove = true;
3701 				}
3702 				if(DANAEMouse.y == DANAESIZY - 1 && mousePosRel.y > 8) {
3703 					mouseDiffY = mousePosRel.y;
3704 					mouseDiffX = 0;
3705 					bKeySpecialMove = true;
3706 				} else if(DANAEMouse.y == 0 && mousePosRel.y < -8) {
3707 					mouseDiffY = mousePosRel.y;
3708 					mouseDiffX = 0;
3709 					bKeySpecialMove = true;
3710 				}
3711 			}
3712 
3713 		}
3714 
3715 		if(GInput->actionPressed(CONTROLS_CUST_CENTERVIEW))
3716 		{
3717 			eyeball.angle.a=eyeball.angle.g=0.f;
3718 			player.desiredangle.a=player.desiredangle.g=player.angle.a=player.angle.g=0.f;
3719 		}
3720 
3721 		float fd = (((float)GInput->getMouseSensitivity()) + 1.f) * 0.1f * ((640.f / (float)DANAESIZX));
3722 		if (fd > 200) {
3723 			fd=200;
3724 		}
3725 
3726 		fd *= ((float)DANAESIZX) * ( 1.0f / 640 );
3727 
3728 		if ((eyeball.exist==2) && (PLAYER_MOUSELOOK_ON||bKeySpecialMove))
3729 		{
3730 			if (mouseDiffY!=0)
3731 			{
3732 				float ia=((float)mouseDiffY*( 1.0f / 5 ))*fd;
3733 
3734 				if (INVERTMOUSE) ia=-ia;
3735 
3736 				if (eyeball.angle.a<70.f)
3737 				{
3738 					if (eyeball.angle.a+ia<70.f) eyeball.angle.a+=ia;
3739 				}
3740 				else if (eyeball.angle.a>300.f)
3741 				{
3742 					if (eyeball.angle.a+ia>300.f) eyeball.angle.a+=ia;
3743 				}
3744 
3745 				eyeball.angle.a=MAKEANGLE(eyeball.angle.a);
3746 			}
3747 
3748 			if (mouseDiffX!=0)
3749 			{
3750 				float ib=((float)mouseDiffX*( 1.0f / 5 ))*fd;
3751 
3752 				eyeball.angle.b=MAKEANGLE(eyeball.angle.b-ib);
3753 			}
3754 		}
3755 		else if (PLAYER_MOUSELOOK_ON || bKeySpecialMove)
3756 			if (ARXmenu.currentmode != AMCM_NEWQUEST)
3757 				{
3758 				if ((mouseDiffY != 0))
3759 					{
3760 						float ia = ((float)mouseDiffY * ( 1.0f / 5 ) * fd);
3761 
3762 						if ((entities.player()) && EEfabs(ia)>2.f) entities.player()->lastanimtime=0;
3763 
3764 						if (INVERTMOUSE) ia=-ia;
3765 
3766 						float iangle=player.angle.a;
3767 
3768 						player.desiredangle.a=player.angle.a;
3769 						player.desiredangle.a+=ia;
3770 						player.desiredangle.a=MAKEANGLE(player.desiredangle.a);
3771 
3772 						if ((player.desiredangle.a>=74.9f) && (player.desiredangle.a<=301.f))
3773 						{
3774 							if (iangle<75.f) player.desiredangle.a=74.9f; //69
3775 							else player.desiredangle.a=301.f;
3776 						}
3777 
3778 					}
3779 
3780 				if ((mouseDiffX != 0))
3781 					{
3782 						float ib = ((float)mouseDiffX * ( 1.0f / 5 ) * fd);
3783 
3784 						if (ib!=0.f) player.Current_Movement|=PLAYER_ROTATE;
3785 
3786 						player.desiredangle.b=player.angle.b;
3787 						player.desiredangle.b=MAKEANGLE(player.desiredangle.b-ib);
3788 						PLAYER_ROTATION=ib;
3789 					}
3790 			}
3791 	}
3792 
3793 	{
3794 
3795 		if ((!BLOCK_PLAYER_CONTROLS) && !(player.Interface & INTER_COMBATMODE))
3796 			{
3797 				if (DRAGINTER == NULL) {
3798 					if ((LastMouseClick & 1) && !(EERIEMouseButton & 1) && !(EERIEMouseButton & 4) && !(LastMouseClick & 4))
3799 					{
3800 						Entity * temp;
3801 					temp = FlyingOverIO;
3802 
3803 						if(temp && !temp->locname.empty()) {
3804 
3805 							if (((FlyingOverIO->ioflags & IO_ITEM) && FlyingOverIO->_itemdata->equipitem)
3806 								&& (player.Full_Skill_Object_Knowledge + player.Full_Attribute_Mind
3807 								>= FlyingOverIO->_itemdata->equipitem->elements[IO_EQUIPITEM_ELEMENT_Identify_Value].value) )
3808 							{
3809 								SendIOScriptEvent(FlyingOverIO,SM_IDENTIFY);
3810 							}
3811 
3812 							WILLADDSPEECH = getLocalised(temp->locname);
3813 
3814 							if (temp->ioflags & IO_GOLD)
3815 							{
3816 								std::stringstream ss;
3817 								ss << temp->_itemdata->price << " " << WILLADDSPEECH;
3818 								WILLADDSPEECH = ss.str();
3819 							}
3820 
3821 							if ((temp->poisonous>0) && (temp->poisonous_count!=0))
3822 							{
3823 								std::string Text = getLocalised("description_poisoned", "error");
3824 								std::stringstream ss;
3825 								ss << " (" << Text << " " << (int)temp->poisonous << ")";
3826 								WILLADDSPEECH += ss.str();
3827 							}
3828 
3829 							if ((temp->ioflags & IO_ITEM) && (temp->durability<100.f))
3830 							{
3831 								std::string Text = getLocalised("description_durability", "error");
3832 								std::stringstream ss;
3833 								ss << " " << Text << " " << std::fixed << std::setw(3) << std::setprecision(0) << temp->durability << "/" << temp->max_durability;
3834 								WILLADDSPEECH += ss.str();
3835 							}
3836 
3837 						WILLADDSPEECHTIME = (unsigned long)(arxtime);
3838 
3839 						bool bAddText = true;
3840 
3841 							if( (temp->obj)&&
3842 								(temp->obj->pbox)&&
3843 							    (temp->obj->pbox->active == 1))
3844 						{
3845 								bAddText=false;
3846 							}
3847 
3848 						if(bAddText) {
3849 								Rect::Num x = checked_range_cast<Rect::Num>(120 * Xratio);
3850 								Rect::Num y = checked_range_cast<Rect::Num>(14 * Yratio);
3851 								Rect::Num w = checked_range_cast<Rect::Num>((120 + 500) * Xratio);
3852 								Rect::Num h = checked_range_cast<Rect::Num>((14 + 200) * Yratio);
3853 								Rect rDraw(x, y, w, h);
3854 								pTextManage->Clear();
3855 								pTextManage->AddText(hFontInBook, WILLADDSPEECH, rDraw, Color(232, 204, 143), 2000 + WILLADDSPEECH.length()*60);
3856 							}
3857 
3858 							WILLADDSPEECH.clear();
3859 						}
3860 					}
3861 					else
3862 					{
3863 						if(config.input.autoDescription)
3864 					{
3865 
3866 								Entity * temp;
3867 						temp = FlyingOverIO;
3868 
3869 								if(temp && !temp->locname.empty()) {
3870 
3871 									if (((FlyingOverIO->ioflags & IO_ITEM) && FlyingOverIO->_itemdata->equipitem)
3872 										&& (player.Full_Skill_Object_Knowledge + player.Full_Attribute_Mind
3873 										>= FlyingOverIO->_itemdata->equipitem->elements[IO_EQUIPITEM_ELEMENT_Identify_Value].value) )
3874 									{
3875 										SendIOScriptEvent(FlyingOverIO,SM_IDENTIFY);
3876 									}
3877 
3878 									WILLADDSPEECH = getLocalised(temp->locname);
3879 
3880 									if (temp->ioflags & IO_GOLD)
3881 									{
3882 										std::stringstream ss;
3883 										ss << temp->_itemdata->price << " " << WILLADDSPEECH;
3884 										WILLADDSPEECH = ss.str();
3885 									}
3886 
3887 									if ((temp->poisonous>0) && (temp->poisonous_count!=0))
3888 									{
3889 										std::string Text = getLocalised("description_poisoned", "error");
3890 										std::stringstream ss;
3891 										ss << WILLADDSPEECH << " (" << Text << " " << (int)temp->poisonous << ")";
3892 										WILLADDSPEECH = ss.str();
3893 									}
3894 
3895 									if ((temp->ioflags & IO_ITEM) && (temp->durability<100.f))
3896 									{
3897 										std::string Text = getLocalised("description_durability", "error");
3898 										std::stringstream ss;
3899 										ss << WILLADDSPEECH << " " << Text << " " << std::fixed << std::setw(3) << std::setprecision(0) << temp->durability << "/" << temp->max_durability;
3900 										WILLADDSPEECH = ss.str();
3901 									}
3902 
3903 									WILLADDSPEECHTIME = (unsigned long)(arxtime);//treat warning C4244 conversion from 'float' to 'unsigned long'
3904 									bool bAddText=true;
3905 
3906 									if( (temp->obj)&&
3907 										(temp->obj->pbox)&&
3908 							        (temp->obj->pbox->active == 1))
3909 							{
3910 										bAddText=false;
3911 									}
3912 
3913 							if(bAddText) {
3914 								Rect::Num x = checked_range_cast<Rect::Num>(120 * Xratio);
3915 								Rect::Num y = checked_range_cast<Rect::Num>(14 * Yratio);
3916 								Rect::Num w = checked_range_cast<Rect::Num>((120 + 500 ) * Xratio);
3917 								Rect::Num h = checked_range_cast<Rect::Num>((14 + 200 ) * Yratio);
3918 								Rect rDraw(x, y, w, h);
3919 								pTextManage->Clear();
3920 								pTextManage->AddText(hFontInBook, WILLADDSPEECH, rDraw, Color(232, 204, 143));
3921 							}
3922 
3923 									WILLADDSPEECH.clear();
3924 								}
3925 							}
3926 					}
3927 				}
3928 			}
3929 
3930 			if ((EERIEMouseButton & 4) || (LastMouseClick & 4))
3931                 WILLADDSPEECH.clear();
3932 
3933 			if (!WILLADDSPEECH.empty())
3934 				if (WILLADDSPEECHTIME+300<arxtime.get_frame_time())
3935 				{
3936 					ARX_SPEECH_Add(WILLADDSPEECH);
3937 					WILLADDSPEECH.clear();
3938 				}
3939 	}
3940 }
3941 
3942 static float fDecPulse;
3943 //-----------------------------------------------------------------------------
ARX_INTERFACE_DrawSecondaryInventory(bool _bSteal)3944 void ARX_INTERFACE_DrawSecondaryInventory(bool _bSteal) {
3945 
3946 	if(TSecondaryInventory->io && !TSecondaryInventory->io->inventory_skin.empty()) {
3947 
3948 		res::path file = "graph/interface/inventory" / TSecondaryInventory->io->inventory_skin;
3949 
3950 		TextureContainer * tc = TextureContainer::LoadUI(file);
3951 
3952 		if(tc) {
3953 			ITC.Set("ingame_inventory", tc);
3954 		} else {
3955 			ITC.Set("ingame_inventory", BasicInventorySkin);
3956 		}
3957 
3958 	} else if(ITC.Get("ingame_inventory") != BasicInventorySkin) {
3959 		ITC.Set("ingame_inventory", BasicInventorySkin);
3960 	}
3961 
3962 	ARX_INTERFACE_DrawItem(ITC.Get("ingame_inventory"), INTERFACE_RATIO(InventoryX), 0.f);
3963 
3964 
3965 	long i,j;
3966 
3967 	for (j=0;j<TSecondaryInventory->sizey;j++)
3968 	{
3969 		for (i=0;i<TSecondaryInventory->sizex;i++)
3970 		{
3971 			Entity * io=TSecondaryInventory->slot[i][j].io;
3972 
3973 			if (io!=NULL)
3974 			{
3975 				bool bItemSteal = false;
3976 				TextureContainer * tc=io->inv;
3977 				TextureContainer * tc2=NULL;
3978 
3979 				if (NeedHalo(io)) tc2 = io->inv->getHalo();
3980 
3981 				if (_bSteal)
3982 				{
3983 					if (!ARX_PLAYER_CanStealItem(io))
3984 					{
3985 						bItemSteal = true;
3986 						tc = ITC.Get("item_cant_steal");
3987 						tc2 = NULL;
3988 					}
3989 				}
3990 
3991 				if ((tc!=NULL) && (TSecondaryInventory->slot[i][j].show || bItemSteal) )
3992 				{
3993 					if (io->ioflags & IO_GOLD)
3994 					{
3995 						long num=0;
3996 
3997 						if (io->_itemdata->price<=3)
3998 							num=io->_itemdata->price-1;
3999 						else if (io->_itemdata->price<=8)
4000 							num=3;
4001 						else if (io->_itemdata->price<=20)
4002 							num=4;
4003 						else if (io->_itemdata->price<=50)
4004 							num=5;
4005 						else
4006 							num=6;
4007 
4008 						io->obj=GoldCoinsObj[num];
4009 						io->inv=GoldCoinsTC[num];
4010 					}
4011 
4012 					float px = INTERFACE_RATIO(InventoryX) + (float)i*INTERFACE_RATIO(32) + INTERFACE_RATIO(2);
4013 					float py = (float)j*INTERFACE_RATIO(32) + INTERFACE_RATIO(13);
4014 
4015 					Color color = (io->poisonous && io->poisonous_count!=0) ? Color::green : Color::white;
4016 					EERIEDrawBitmap(px, py, INTERFACE_RATIO_DWORD(tc->m_dwWidth),
4017 					                INTERFACE_RATIO_DWORD(tc->m_dwHeight), 0.001f, tc, color);
4018 
4019 					if (!bItemSteal && (io==FlyingOverIO))
4020 					{
4021 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
4022 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
4023 						EERIEDrawBitmap(px, py, INTERFACE_RATIO_DWORD(tc->m_dwWidth),
4024 						                INTERFACE_RATIO_DWORD(tc->m_dwHeight), 0.001f, tc, Color::white);
4025 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
4026 					}
4027 					else if(!bItemSteal && (io->ioflags & IO_CAN_COMBINE)) {
4028 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
4029 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
4030 
4031 						float fColorPulse = fabs(cos(radians(fDecPulse)));
4032 						EERIEDrawBitmap(px, py, INTERFACE_RATIO_DWORD(tc->m_dwWidth),
4033 						                INTERFACE_RATIO_DWORD(tc->m_dwHeight), 0.001f, tc,
4034 						                Color::gray(fColorPulse));
4035 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
4036 					}
4037 
4038 					if (tc2!=NULL)
4039 					{
4040 						ARX_INTERFACE_HALO_Draw(io,tc,tc2,
4041 							px,
4042 							py, INTERFACE_RATIO(1), INTERFACE_RATIO(1));
4043 					}
4044 
4045 					if ((io->ioflags & IO_ITEM) && (io->_itemdata->count!=1))
4046 						ARX_INTERFACE_DrawNumber(px, py, io->_itemdata->count, 3, Color::white);
4047 				}
4048 			}
4049 		}
4050 	}
4051 }
4052 
4053 //-----------------------------------------------------------------------------
ARX_INTERFACE_DrawInventory(short _sNum,int _iX=0,int _iY=0)4054 void ARX_INTERFACE_DrawInventory(short _sNum, int _iX=0, int _iY=0)
4055 {
4056 	fDecPulse += FrameDiff * 0.5f;
4057 
4058 	float fCenterX	= DANAECENTERX - INTERFACE_RATIO(320) + INTERFACE_RATIO(35) + _iX ;
4059 	float fSizY		= DANAESIZY - INTERFACE_RATIO(101) + INTERFACE_RATIO_LONG(InventoryY) + _iY;
4060 
4061 	float fPosX = ARX_CAST_TO_INT_THEN_FLOAT( fCenterX );
4062 	float fPosY = ARX_CAST_TO_INT_THEN_FLOAT( fSizY );
4063 
4064 	ARX_INTERFACE_DrawItem(ITC.Get("hero_inventory"), fPosX, fPosY - INTERFACE_RATIO(5));
4065 
4066 	for (size_t j=0;j<INVENTORY_Y;j++)
4067 		for (size_t i=0;i<INVENTORY_X;i++)
4068 		{
4069 			Entity * io = inventory[_sNum][i][j].io;
4070 
4071 			if ((io!=NULL) && (inventory[_sNum][i][j].show))
4072 			{
4073 				TextureContainer * tc=io->inv;
4074 				TextureContainer * tc2=NULL;
4075 
4076 				if (NeedHalo(io))
4077 					tc2 = io->inv->getHalo();
4078 
4079 				if(tc != NULL) {
4080 
4081 					float px = fPosX + i*INTERFACE_RATIO(32) + INTERFACE_RATIO(7);
4082 					float py = fPosY + j*INTERFACE_RATIO(32) + INTERFACE_RATIO(6);
4083 
4084 					Color color = (io->poisonous && io->poisonous_count != 0) ? Color::green : Color::white;
4085 					EERIEDrawBitmap(px, py, INTERFACE_RATIO_DWORD(tc->m_dwWidth),
4086 					                INTERFACE_RATIO_DWORD(tc->m_dwHeight), 0.001f, tc, color);
4087 
4088 					if(io == FlyingOverIO) {
4089 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
4090 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
4091 						EERIEDrawBitmap(px, py, INTERFACE_RATIO_DWORD(tc->m_dwWidth),
4092 						                INTERFACE_RATIO_DWORD(tc->m_dwHeight), 0.001f, tc, Color::white);
4093 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
4094 					} else if(io->ioflags & IO_CAN_COMBINE) {
4095 						float fColorPulse = fabs(cos(radians(fDecPulse)));
4096 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
4097 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
4098 						EERIEDrawBitmap(px, py, INTERFACE_RATIO_DWORD(tc->m_dwWidth),
4099 						                INTERFACE_RATIO_DWORD(tc->m_dwHeight), 0.001f, tc,
4100 						                Color::gray(fColorPulse));
4101 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
4102 					}
4103 
4104 					if (tc2)
4105 					{
4106 						ARX_INTERFACE_HALO_Render(
4107 							io->halo.color.r, io->halo.color.g, io->halo.color.b,
4108 							io->halo.flags,
4109 							tc2,
4110 							px,
4111 							py, INTERFACE_RATIO(1), INTERFACE_RATIO(1));
4112 					}
4113 
4114 					if ((io->ioflags & IO_ITEM) && (io->_itemdata->count!=1))
4115 						ARX_INTERFACE_DrawNumber(px, py, io->_itemdata->count, 3, Color::white);
4116 				}
4117 			}
4118 		}
4119 }
4120 
4121 extern TextureContainer * stealth_gauge_tc;
4122 extern float CURRENT_PLAYER_COLOR;
4123 
4124 // Stealth Gauge Drawing
ARX_INTERFACE_Draw_Stealth_Gauge()4125 void ARX_INTERFACE_Draw_Stealth_Gauge() {
4126 
4127 	if ((stealth_gauge_tc) && (!CINEMASCOPE))
4128 	{
4129 		float v=GetPlayerStealth();
4130 
4131 		if (CURRENT_PLAYER_COLOR<v)
4132 		{
4133 			float px = INTERFACE_RATIO(InventoryX) + INTERFACE_RATIO(110);
4134 			if (px < INTERFACE_RATIO(10)) px = INTERFACE_RATIO(10);
4135 
4136 			float py = DANAESIZY - INTERFACE_RATIO(126 + 32);
4137 			float t=v-CURRENT_PLAYER_COLOR;
4138 
4139 			if (t>=15) v=1.f;
4140 			else v=(t*( 1.0f / 15 ))*0.9f+0.1f;
4141 
4142 			GRenderer->SetRenderState(Renderer::AlphaBlending, true);
4143 			GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
4144 			EERIEDrawBitmap(px, py, INTERFACE_RATIO_DWORD(stealth_gauge_tc->m_dwWidth),
4145 			                INTERFACE_RATIO_DWORD(stealth_gauge_tc->m_dwHeight), 0.01f,
4146 			                stealth_gauge_tc, Color::gray(v));
4147 			GRenderer->SetRenderState(Renderer::AlphaBlending, false);
4148 		}
4149 	}
4150 }
4151 
4152 //-----------------------------------------------------------------------------
4153 // Damaged Equipment Drawing
4154 //-----------------------------------------------------------------------------
ARX_INTERFACE_DrawDamagedEquipment()4155 void ARX_INTERFACE_DrawDamagedEquipment()
4156 {
4157 	if (CINEMASCOPE || BLOCK_PLAYER_CONTROLS) return;
4158 
4159 	if (player.Interface & INTER_INVENTORYALL) return;
4160 
4161 	long needdraw=0;
4162 
4163 	for (long i=0;i<5;i++)
4164 	{
4165 		if (iconequip[i])
4166 		{
4167 			long eq=-1;
4168 
4169 			switch (i)
4170 			{
4171 				case 0:
4172 					eq = EQUIP_SLOT_WEAPON;
4173 					break;
4174 				case 1:
4175 					eq = EQUIP_SLOT_SHIELD;
4176 					break;
4177 				case 2:
4178 					eq = EQUIP_SLOT_HELMET;
4179 					break;
4180 				case 3:
4181 					eq = EQUIP_SLOT_ARMOR;
4182 					break;
4183 				case 4:
4184 					eq = EQUIP_SLOT_LEGGINGS;
4185 					break;
4186 			}
4187 
4188 			if (player.equiped[eq]>0)
4189 			{
4190 				Entity * io=entities[player.equiped[eq]];
4191 				float ratio=io->durability/io->max_durability;
4192 
4193 				if (ratio<=0.5f)
4194 				{
4195 					needdraw|=1<<i;
4196 				}
4197 			}
4198 		}
4199 	}
4200 
4201 	if (needdraw)
4202 	{
4203 		GRenderer->SetRenderState(Renderer::AlphaBlending, true);
4204 		GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
4205 
4206 		GRenderer->SetCulling(Renderer::CullNone);
4207 		GRenderer->SetRenderState(Renderer::DepthWrite, true);
4208 		GRenderer->SetRenderState(Renderer::Fog, false);
4209 
4210 		float px = INTERFACE_RATIO(InventoryX) + INTERFACE_RATIO(10 + 32 + 100);
4211 
4212 		if ( px < INTERFACE_RATIO( 10 + 32 ) ) px = INTERFACE_RATIO( 10 + 32 );
4213 
4214 		float py = DANAESIZY - INTERFACE_RATIO(158);
4215 
4216 		for (long i=0;i<5;i++)
4217 		{
4218 			if ( (needdraw&(1<<i))&&
4219 				 (iconequip[i]) )
4220 			{
4221 				long eq=-1;
4222 
4223 				switch (i)
4224 				{
4225 					case 0:
4226 						eq = EQUIP_SLOT_WEAPON;
4227 						break;
4228 					case 1:
4229 						eq = EQUIP_SLOT_SHIELD;
4230 						break;
4231 					case 2:
4232 						eq = EQUIP_SLOT_HELMET;
4233 						break;
4234 					case 3:
4235 						eq = EQUIP_SLOT_ARMOR;
4236 						break;
4237 					case 4:
4238 						eq = EQUIP_SLOT_LEGGINGS;
4239 						break;
4240 				}
4241 
4242 				if (player.equiped[eq]>0)
4243 				{
4244 					Entity * io=entities[player.equiped[eq]];
4245 					float ratio=io->durability/io->max_durability;
4246 					Color col = Color3f(1.f-ratio, ratio, 0).to<u8>();
4247 					EERIEDrawBitmap2(px, py, INTERFACE_RATIO_DWORD(iconequip[i]->m_dwWidth),
4248 					                 INTERFACE_RATIO_DWORD(iconequip[i]->m_dwHeight), 0.001f, iconequip[i], col);
4249 				}
4250 			}
4251 		}
4252 
4253 		currpos += static_cast<long>(INTERFACE_RATIO(33.f));
4254 		GRenderer->SetRenderState(Renderer::AlphaBlending, false);
4255 	}
4256 }
4257 
4258 //-----------------------------------------------------------------------------
ARX_INTERFACE_RELEASESOUND()4259 void ARX_INTERFACE_RELEASESOUND()
4260 {
4261 	ARX_SOUND_PlayInterface(SND_MENU_RELEASE);
4262 }
4263 
4264 //-----------------------------------------------------------------------------
ARX_INTERFACE_ERRORSOUND()4265 void ARX_INTERFACE_ERRORSOUND()
4266 {
4267 	ARX_SOUND_PlayInterface(SND_MENU_CLICK);
4268 }
4269 
4270 //-----------------------------------------------------------------------------
CheckAttributeClick(float x,float y,float * val,TextureContainer * tc)4271 bool CheckAttributeClick(float x, float y, float * val, TextureContainer * tc)
4272 {
4273 	bool rval=false;
4274 	float t;
4275 	t=*val;
4276 
4277 	if (MouseInBookRect(x,y,x+32,y+32))
4278 	{
4279 		rval=true;
4280 
4281 		if (((BOOKBUTTON & 1) || (BOOKBUTTON & 2))&& (tc))
4282 			DrawBookInterfaceItem(tc, x, y);
4283 
4284 		if (!(BOOKBUTTON & 1) && (LASTBOOKBUTTON & 1))
4285 		{
4286 			if ((player.Attribute_Redistribute > 0))
4287 			{
4288 				player.Attribute_Redistribute--;
4289 				t++;
4290 				*val=t;
4291 				ARX_INTERFACE_RELEASESOUND();
4292 			}
4293 			else ARX_INTERFACE_ERRORSOUND();
4294 		}
4295 
4296 		if (!(BOOKBUTTON & 2) && (LASTBOOKBUTTON & 2))
4297 		{
4298 			if (ARXmenu.currentmode == AMCM_NEWQUEST)
4299 			{
4300 				if ((t >6) && (player.level==0))
4301 				{
4302 					player.Attribute_Redistribute++;
4303 					t --;
4304 					*val=t;
4305 					ARX_INTERFACE_RELEASESOUND();
4306 				}
4307 				else ARX_INTERFACE_ERRORSOUND();
4308 			}
4309 			else ARX_INTERFACE_ERRORSOUND();
4310 		}
4311 	}
4312 
4313 	return rval;
4314 }
4315 
4316 //-----------------------------------------------------------------------------
CheckSkillClick(float x,float y,float * val,TextureContainer * tc,float * oldval)4317 bool CheckSkillClick(float x, float y, float * val, TextureContainer * tc, float * oldval)
4318 {
4319 	bool rval=false;
4320 	float t,ot;
4321 	t=*val;
4322 	ot=*oldval;
4323 
4324 	if ( MouseInBookRect( x, y, x + 32, y + 32 ) )
4325 	{
4326 		rval=true;
4327 
4328 		if (((BOOKBUTTON & 1) || (BOOKBUTTON & 2))&& (tc))
4329 			DrawBookInterfaceItem(tc, x, y);
4330 
4331 		if (!(BOOKBUTTON & 1) && (LASTBOOKBUTTON & 1))
4332 		{
4333 			if ((player.Skill_Redistribute > 0))
4334 			{
4335 				player.Skill_Redistribute--;
4336 				t++;
4337 				*val=t;
4338 				ARX_INTERFACE_RELEASESOUND();
4339 			}
4340 			else ARX_INTERFACE_ERRORSOUND();
4341 		}
4342 
4343 		if (!(BOOKBUTTON & 2) && (LASTBOOKBUTTON & 2))
4344 		{
4345 			if (ARXmenu.currentmode == AMCM_NEWQUEST)
4346 			{
4347 				if ((t > ot) && (player.level==0))
4348 				{
4349 					player.Skill_Redistribute++;
4350 					t --;
4351 					*val=t;
4352 					ARX_INTERFACE_RELEASESOUND();
4353 				}
4354 				else ARX_INTERFACE_ERRORSOUND();
4355 			}
4356 			else ARX_INTERFACE_ERRORSOUND();
4357 		}
4358 	}
4359 
4360 	return rval;
4361 }
4362 
4363 //AFFICHAGE ICONE DE SPELLS DE DURATION
4364 
StdDraw(float posx,float posy,Color color,TextureContainer * tcc,long flag,long i)4365 static void StdDraw(float posx, float posy, Color color, TextureContainer * tcc, long flag, long i) {
4366 
4367 	TextureContainer * tc;
4368 
4369 	if (tcc==NULL)
4370 	{
4371 		if (ITC.Get("unknown")==NULL)
4372 			ITC.Set("unknown", TextureContainer::Load("graph/interface/icons/spell_unknown"));
4373 
4374 		tc=ITC.Get("unknown");
4375 	}
4376 	else tc=tcc;
4377 
4378 	if (tc)
4379 	{
4380 		EERIEDrawBitmap(posx, posy, INTERFACE_RATIO_DWORD(tc->m_dwWidth) * 0.5f, INTERFACE_RATIO_DWORD(tc->m_dwHeight) * 0.5f, 0.01f, tc, color);
4381 
4382 		if(flag & 2) {
4383 			GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendOne);
4384 			EERIEDrawBitmap(posx - 1, posy - 1, INTERFACE_RATIO_DWORD(tc->m_dwWidth) * 0.5f, INTERFACE_RATIO_DWORD(tc->m_dwHeight) * 0.5f, 0.0001f, tc, color);
4385 			EERIEDrawBitmap(posx + 1, posy + 1, INTERFACE_RATIO_DWORD(tc->m_dwWidth) * 0.5f, INTERFACE_RATIO_DWORD(tc->m_dwHeight) * 0.5f, 0.0001f, tc, color);
4386 			GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
4387 		}
4388 
4389 		if (!(flag & 1))
4390 		{
4391 			if (!(player.Interface & INTER_COMBATMODE))
4392 				if (MouseInRect(posx,posy, posx+INTERFACE_RATIO(32),posy+INTERFACE_RATIO(32)))
4393 				{
4394 					SpecialCursor=CURSOR_INTERACTION_ON;
4395 
4396 					if ((LastMouseClick & 1) && (!(EERIEMouseButton & 1)) )
4397 					{
4398 						if (flag & 2)
4399 						{
4400 							if (Precast[PRECAST_NUM].typ >= 0)
4401 								WILLADDSPEECH = spellicons[Precast[PRECAST_NUM].typ].name;
4402 
4403 							WILLADDSPEECHTIME = (unsigned long)(arxtime);
4404 						}
4405 						else
4406 						{
4407 							if (spells[i].type >= 0)
4408 								WILLADDSPEECH = spellicons[spells[i].type].name;
4409 
4410 							WILLADDSPEECHTIME = (unsigned long)(arxtime);
4411 						}
4412 					}
4413 
4414 					if (EERIEMouseButton & 4)
4415 					{
4416 						if (flag & 2)
4417 						{
4418 							ARX_SPELLS_Precast_Launch(PRECAST_NUM);
4419 							EERIEMouseButton&=~4;
4420 						}
4421 						else
4422 						{
4423 							ARX_SPELLS_AbortSpellSound();
4424 							EERIEMouseButton&=~4;
4425 							spells[i].tolive=0;
4426 						}
4427 					}
4428 				}
4429 		}
4430 	}
4431 }
4432 //---------------------------------------------------------------------------
ManageSpellIcon(long i,float rrr,long flag)4433 void ManageSpellIcon(long i,float rrr,long flag)
4434 {
4435 	float POSX = DANAESIZX-INTERFACE_RATIO(35);
4436 	Color color;
4437 	float posx = POSX+lSLID_VALUE;
4438 	float posy = (float)currpos;
4439 	Spell typ=spells[i].type;
4440 
4441 	if(flag & 1) {
4442 		color = Color3f(rrr, 0, 0).to<u8>();
4443 	} else if(flag & 2) {
4444 		color = Color3f(0, rrr * (1.0f/2), rrr).to<u8>();
4445 		float px = INTERFACE_RATIO(InventoryX) + INTERFACE_RATIO(110);
4446 		if(px < INTERFACE_RATIO(10)) {
4447 			px = INTERFACE_RATIO(10);
4448 		}
4449 		posx = px + INTERFACE_RATIO(33 + 33 + 33) + PRECAST_NUM * INTERFACE_RATIO(33);
4450 		posy = DANAESIZY - INTERFACE_RATIO(126+32); // niveau du stealth
4451 		typ = (Spell)i; // TODO ugh
4452 	} else {
4453 		color = Color::gray(rrr);
4454 	}
4455 
4456 	bool bOk=true;
4457 
4458 	if (spells[i].bDuration)
4459 	{
4460 		if(	(player.mana<20)||
4461 			((spells[i].timcreation+spells[i].tolive - float(arxtime)) < 2000) )
4462 		{
4463 			if(ucFlick&1) bOk=false;
4464 		}
4465 	}
4466 	else
4467 	{
4468 		if(player.mana<20)
4469 		{
4470 			if(ucFlick&1) bOk=false;
4471 		}
4472 	}
4473 
4474 	if ( ( (bOk) && (typ>=0) &&	((size_t)typ<SPELL_COUNT) ) || (flag == 2) )
4475 		StdDraw(posx,posy,color,spellicons[typ].tc,flag,i);
4476 
4477 	currpos += static_cast<long>(INTERFACE_RATIO(33.f));
4478 }
4479 extern float GLOBAL_LIGHT_FACTOR;
4480 //-----------------------------------------------------------------------------
ARX_INTERFACE_ManageOpenedBook_Finish()4481 void ARX_INTERFACE_ManageOpenedBook_Finish()
4482 {
4483 	GRenderer->SetRenderState(Renderer::DepthWrite, true);
4484 
4485 	if ((player.Interface & INTER_MAP ) &&  (!(player.Interface & INTER_COMBATMODE)))
4486 	{
4487 		if (Book_Mode == BOOKMODE_SPELLS)
4488 		{
4489 			Anglef angle;
4490 			Vec3f pos;
4491 
4492 			EERIE_LIGHT tl;
4493 			memcpy(&tl,&DynLight[0],sizeof(EERIE_LIGHT));
4494 
4495 			DynLight[0].pos = Vec3f(500.f, -1960.f, 1590.f);
4496 			DynLight[0].exist = 1;
4497 			DynLight[0].rgb = Color3f(0.6f, 0.7f, 0.9f);
4498 			DynLight[0].intensity  = 1.8f;
4499 			DynLight[0].fallstart=4520.f;
4500 			DynLight[0].fallend = DynLight[0].fallstart + 600.f;
4501 			DynLight[0].rgb255 = DynLight[0].rgb * 255.f;
4502 			DynLight[0].falldiff = DynLight[0].fallend-DynLight[0].fallstart;
4503 			DynLight[0].falldiffmul = 1.f / DynLight[0].falldiff;
4504 			DynLight[0].precalc = DynLight[0].intensity * GLOBAL_LIGHT_FACTOR;
4505 
4506 			EERIE_CAMERA * oldcam=ACTIVECAM;
4507 			bookcam.center = Vec2i(DANAECENTERX, DANAECENTERY);
4508 			SetActiveCamera(&bookcam);
4509 			PrepareCamera(&bookcam);
4510 
4511 			pos = Vec3f(0.f, 0.f, 2100.f);
4512 			angle = Anglef::ZERO;
4513 
4514 			PDL[0]=&DynLight[0];
4515 			TOTPDL=1;
4516 
4517 			long found2=0;
4518 			float n;
4519 			long xpos=0;
4520 			long ypos=0;
4521 
4522 			for(size_t i = 0; i < RUNE_COUNT; i++) {
4523 
4524 				if (necklace.runes[i])
4525 				{
4526 					bookcam.center.x = (382 + xpos * 45 + BOOKDECX) * Xratio;
4527 					bookcam.center.y = (100 + ypos * 64 + BOOKDECY) * Yratio;
4528 
4529 					SetActiveCamera(&bookcam);
4530 					PrepareCamera(&bookcam);
4531 
4532 					// First draw the lace
4533 					angle.b=0.f;
4534 
4535 					if (player.rune_flags & (RuneFlag)(1<<i))
4536 					{
4537 						DrawEERIEInter(necklace.lacet,&angle,&pos,NULL);
4538 
4539 						if (necklace.runes[i]->angle.b!=0.f)
4540 						{
4541 							if (necklace.runes[i]->angle.b>300.f)
4542 								necklace.runes[i]->angle.b=300.f;
4543 
4544 							angle.b=EEsin(arxtime.get_updated() * ( 1.0f / 200 ))*necklace.runes[i]->angle.b*( 1.0f / 40 );
4545 						}
4546 
4547 						necklace.runes[i]->angle.b-=framedelay*0.2f;
4548 
4549 						if (necklace.runes[i]->angle.b<0.f) necklace.runes[i]->angle.b=0.f;
4550 
4551 						DynLight[0].exist=0;
4552 						float tt;
4553 
4554 						bookcam.center.x = (382 + xpos * 45 + BOOKDECX + 3) * Xratio;
4555 						bookcam.center.y = (100 + ypos * 64 + BOOKDECY + 2) * Yratio;
4556 						SetActiveCamera(&bookcam);
4557 						PrepareCamera(&bookcam);
4558 
4559 						tt=angle.b;
4560 						angle.b=-20.f;
4561 						angle.b=tt;
4562 						angle.b-=20.f;
4563 
4564 						angle.b+=20.f;
4565 						GRenderer->SetRenderState(Renderer::DepthWrite, true);
4566 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
4567 						DynLight[0].exist=1;
4568 
4569 						bookcam.center.x = (382 + xpos * 45 + BOOKDECX) * Xratio;
4570 						bookcam.center.y = (100 + ypos * 64 + BOOKDECY) * Yratio;
4571 						SetActiveCamera(&bookcam);
4572 						PrepareCamera(&bookcam);
4573 
4574 						// Now draw the rune
4575 						DrawEERIEInter(necklace.runes[i],&angle,&pos,NULL);
4576 
4577 						PopAllTriangleList();
4578 
4579 						xpos++;
4580 
4581 						if (xpos > 4)
4582 						{
4583 							xpos = 0;
4584 							ypos++;
4585 						}
4586 
4587 						// Checks for Mouse floating over a rune...
4588 						if ((!found2) &&
4589 							MouseInRect(BBOXMIN.x, BBOXMIN.y, BBOXMAX.x, BBOXMAX.y))
4590 						{
4591 							long r=0;
4592 
4593 							for (size_t j=0;j<necklace.runes[i]->facelist.size();j++)
4594 							{
4595 								n=PtIn2DPolyProj( necklace.runes[i], &necklace.runes[i]->facelist[j] , (float)DANAEMouse.x, (float)DANAEMouse.y);
4596 
4597 								if (n!=0.f)
4598 								{
4599 									r=1;
4600 									break;
4601 								}
4602 							}
4603 
4604 							if (r)
4605 							{
4606 								GRenderer->SetRenderState(Renderer::AlphaBlending, true);
4607 								GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
4608 								DrawEERIEInter(necklace.runes[i],&angle,&pos,NULL);
4609 
4610 								necklace.runes[i]->angle.b+=framedelay*2.f;
4611 
4612 								PopAllTriangleList();
4613 
4614 								GRenderer->SetRenderState(Renderer::AlphaBlending, false);
4615 
4616 								SpecialCursor=CURSOR_INTERACTION_ON;
4617 
4618 								if ((EERIEMouseButton & 1)  && !(LastMouseClick & 1))
4619 									if ((size_t)LastRune!=i)
4620 									{
4621 										switch(i)
4622 										{
4623 										case RUNE_AAM:
4624 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "aam", ARX_SOUND_GetDuration(SND_SYMB_AAM));
4625 											ARX_SOUND_PlayInterface(SND_SYMB_AAM);
4626 											break;
4627 										case RUNE_CETRIUS:
4628 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "cetrius", ARX_SOUND_GetDuration(SND_SYMB_CETRIUS));
4629 											ARX_SOUND_PlayInterface(SND_SYMB_CETRIUS);
4630 											break;
4631 										case RUNE_COMUNICATUM:
4632 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "comunicatum", ARX_SOUND_GetDuration(SND_SYMB_COMUNICATUM));
4633 											ARX_SOUND_PlayInterface(SND_SYMB_COMUNICATUM);
4634 											break;
4635 										case RUNE_COSUM:
4636 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "cosum", ARX_SOUND_GetDuration(SND_SYMB_COSUM));
4637 											ARX_SOUND_PlayInterface(SND_SYMB_COSUM);
4638 											break;
4639 										case RUNE_FOLGORA:
4640 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "folgora", ARX_SOUND_GetDuration(SND_SYMB_FOLGORA));
4641 											ARX_SOUND_PlayInterface(SND_SYMB_FOLGORA);
4642 											break;
4643 										case RUNE_FRIDD:
4644 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "fridd", ARX_SOUND_GetDuration(SND_SYMB_FRIDD));
4645 											ARX_SOUND_PlayInterface(SND_SYMB_FRIDD);
4646 											break;
4647 										case RUNE_KAOM:
4648 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "kaom", ARX_SOUND_GetDuration(SND_SYMB_KAOM));
4649 											ARX_SOUND_PlayInterface(SND_SYMB_KAOM);
4650 											break;
4651 										case RUNE_MEGA:
4652 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "mega", ARX_SOUND_GetDuration(SND_SYMB_MEGA));
4653 											ARX_SOUND_PlayInterface(SND_SYMB_MEGA);
4654 											break;
4655 										case RUNE_MORTE:
4656 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "morte", ARX_SOUND_GetDuration(SND_SYMB_MORTE));
4657 											ARX_SOUND_PlayInterface(SND_SYMB_MORTE);
4658 											break;
4659 										case RUNE_MOVIS:
4660 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "movis", ARX_SOUND_GetDuration(SND_SYMB_MOVIS));
4661 											ARX_SOUND_PlayInterface(SND_SYMB_MOVIS);
4662 											break;
4663 										case RUNE_NHI:
4664 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "nhi", ARX_SOUND_GetDuration(SND_SYMB_NHI));
4665 											ARX_SOUND_PlayInterface(SND_SYMB_NHI);
4666 											break;
4667 										case RUNE_RHAA:
4668 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "rhaa", ARX_SOUND_GetDuration(SND_SYMB_RHAA));
4669 											ARX_SOUND_PlayInterface(SND_SYMB_RHAA);
4670 											break;
4671 										case RUNE_SPACIUM:
4672 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "spacium", ARX_SOUND_GetDuration(SND_SYMB_SPACIUM));
4673 											ARX_SOUND_PlayInterface(SND_SYMB_SPACIUM);
4674 											break;
4675 										case RUNE_STREGUM:
4676 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "stregum", ARX_SOUND_GetDuration(SND_SYMB_STREGUM));
4677 											ARX_SOUND_PlayInterface(SND_SYMB_STREGUM);
4678 											break;
4679 										case RUNE_TAAR:
4680 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "taar", ARX_SOUND_GetDuration(SND_SYMB_TAAR));
4681 											ARX_SOUND_PlayInterface(SND_SYMB_TAAR);
4682 											break;
4683 										case RUNE_TEMPUS:
4684 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "tempus", ARX_SOUND_GetDuration(SND_SYMB_TEMPUS));
4685 											ARX_SOUND_PlayInterface(SND_SYMB_TEMPUS);
4686 											break;
4687 										case RUNE_TERA:
4688 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "tera", ARX_SOUND_GetDuration(SND_SYMB_TERA));
4689 											ARX_SOUND_PlayInterface(SND_SYMB_TERA);
4690 											break;
4691 										case RUNE_VISTA:
4692 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "vista", ARX_SOUND_GetDuration(SND_SYMB_VISTA));
4693 											ARX_SOUND_PlayInterface(SND_SYMB_VISTA);
4694 											break;
4695 										case RUNE_VITAE:
4696 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "vitae", ARX_SOUND_GetDuration(SND_SYMB_VITAE));
4697 											ARX_SOUND_PlayInterface(SND_SYMB_VITAE);
4698 											break;
4699 										case RUNE_YOK:
4700 											ARX_SPELLS_RequestSymbolDraw(entities.player(), "yok", ARX_SOUND_GetDuration(SND_SYMB_YOK));
4701 											ARX_SOUND_PlayInterface(SND_SYMB_YOK);
4702 											break;
4703 										}
4704 									}
4705 
4706 									LastRune=i;
4707 							}
4708 						}
4709 					}
4710 				}
4711 			}
4712 
4713 			GRenderer->SetCulling(Renderer::CullCCW);
4714 
4715 			if (!found2) LastRune=-1;
4716 
4717 			// Now Draws Spells for this level...
4718 			ARX_PLAYER_ComputePlayerFullStats();
4719 
4720 			float posx=0;
4721 			float posy=0;
4722 			float fPosX = 0;
4723 			float fPosY = 0;
4724 			bool	bFlyingOver = false;
4725 
4726 			for (size_t i=0; i < SPELL_COUNT; i++)
4727 			{
4728 				if ((spellicons[i].level==Book_SpellPage) && (!spellicons[i].bSecret))
4729 				{
4730 					// check if player can cast it
4731 					bool bOk = true;
4732 					long j = 0;
4733 
4734 					while ((j < 4) && (spellicons[i].symbols[j] != RUNE_NONE))
4735 					{
4736 						if (!(player.rune_flags & (RuneFlag)(1<<spellicons[i].symbols[j])))
4737 						{
4738 							bOk = false;
4739 						}
4740 
4741 						j++;
4742 					}
4743 
4744 					if (bOk)
4745 					{
4746 						fPosX = 170.f+posx*85.f;
4747 						fPosY = 135.f+posy*70.f;
4748 						long flyingover = 0;
4749 
4750 						if (MouseInBookRect(fPosX, fPosY, fPosX+48, fPosY+48))
4751 						{
4752 							bFlyingOver = true;
4753 							flyingover = 1;
4754 
4755 							SpecialCursor=CURSOR_INTERACTION_ON;
4756 							DrawBookTextCenter(hFontInBook, 208, 90, spellicons[i].name, Color::none);
4757 
4758 							for(size_t si = 0; si < MAX_SPEECH; si++) {
4759 								if(speech[si].timecreation > 0)
4760 									FLYING_OVER=0;
4761 							}
4762 
4763 							OLD_FLYING_OVER = FLYING_OVER;
4764 							pTextManage->Clear();
4765 							UNICODE_ARXDrawTextCenteredScroll(hFontInGame,
4766 								static_cast<float>(DANAECENTERX),
4767 								12,
4768 								(DANAECENTERX)*0.82f,
4769 								spellicons[i].description,
4770 								Color(232,204,143),
4771 								1000,
4772 								0.01f,
4773 								2,
4774 								0);
4775 
4776 							long count = 0;
4777 
4778 							for (long j = 0; j < 6; ++j)
4779 								if (spellicons[i].symbols[j] != RUNE_NONE)
4780 									++count;
4781 
4782 							GRenderer->GetTextureStage(0)->SetMagFilter(TextureStage::FilterLinear);
4783 							for(int j = 0; j < 6; ++j) {
4784 								if(spellicons[i].symbols[j] != RUNE_NONE) {
4785 									pos.x = (240-(count*32)*0.5f+j*32);
4786 									pos.y = (306);
4787 									DrawBookInterfaceItem(necklace.pTexTab[spellicons[i].symbols[j]], pos.x, pos.y);
4788 								}
4789 							}
4790 							GRenderer->GetTextureStage(0)->SetMagFilter(TextureStage::FilterNearest);
4791 						}
4792 
4793 						if (spellicons[i].tc)
4794 						{
4795 							GRenderer->SetRenderState(Renderer::AlphaBlending, true);
4796 							GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor);
4797 
4798 							Color color;
4799 							if(flyingover) {
4800 								color = Color::white;
4801 
4802 								if ((EERIEMouseButton & 1)  && !(LastMouseClick & 1))
4803 								{
4804 									player.SpellToMemorize.bSpell = true;
4805 
4806 									for (long j=0;j<6;j++)
4807 									{
4808 										player.SpellToMemorize.iSpellSymbols[j] = spellicons[i].symbols[j];
4809 									}
4810 
4811 									player.SpellToMemorize.lTimeCreation = (unsigned long)(arxtime);
4812 								}
4813 							} else {
4814 								color = Color::fromBGRA(0xFFa8d0df);
4815 							}
4816 
4817 							GRenderer->GetTextureStage(0)->SetMagFilter(TextureStage::FilterLinear);
4818 							DrawBookInterfaceItem(spellicons[i].tc, fPosX, fPosY, color);
4819 							GRenderer->GetTextureStage(0)->SetMagFilter(TextureStage::FilterNearest);
4820 
4821 							GRenderer->SetRenderState(Renderer::AlphaBlending, false);
4822 						}
4823 
4824 						posx ++;
4825 
4826 						if (posx>=2)
4827 						{
4828 							posx = 0;
4829 							posy ++;
4830 						}
4831 					}
4832 				}
4833 			}
4834 
4835 			if (!bFlyingOver)
4836 			{
4837 				OLD_FLYING_OVER = -1;
4838 				FLYING_OVER = -1;
4839 			}
4840 
4841 			memcpy(&DynLight[0],&tl,sizeof(EERIE_LIGHT));
4842 			SetActiveCamera(oldcam);
4843 			PrepareCamera(oldcam);
4844 		}
4845 	}
4846 
4847 
4848 }
4849 
4850 //-----------------------------------------------------------------------------
ARX_INTERFACE_ManageOpenedBook()4851 void ARX_INTERFACE_ManageOpenedBook()
4852 {
4853 	GRenderer->SetRenderState(Renderer::Fog, false);
4854 
4855 	if (ITC.Get("questbook")==NULL)
4856 	{
4857 		ITC.Set("playerbook", "graph/interface/book/character_sheet/char_sheet_book");
4858 		ITC.Set("ic_casting", "graph/interface/book/character_sheet/buttons_carac/icone_casting");
4859 		ITC.Set("ic_close_combat", "graph/interface/book/character_sheet/buttons_carac/icone_close_combat");
4860 		ITC.Set("ic_constitution", "graph/interface/book/character_sheet/buttons_carac/icone_constit");
4861 		ITC.Set("ic_defense", "graph/interface/book/character_sheet/buttons_carac/icone_defense");
4862 		ITC.Set("ic_dexterity", "graph/interface/book/character_sheet/buttons_carac/icone_dext");
4863 		ITC.Set("ic_etheral_link", "graph/interface/book/character_sheet/buttons_carac/icone_etheral_link");
4864 		ITC.Set("ic_mind", "graph/interface/book/character_sheet/buttons_carac/icone_intel");
4865 		ITC.Set("ic_intuition", "graph/interface/book/character_sheet/buttons_carac/icone_intuition");
4866 		ITC.Set("ic_mecanism", "graph/interface/book/character_sheet/buttons_carac/icone_mecanism");
4867 		ITC.Set("ic_object_knowledge", "graph/interface/book/character_sheet/buttons_carac/icone_obj_knowledge");
4868 		ITC.Set("ic_projectile", "graph/interface/book/character_sheet/buttons_carac/icone_projectile");
4869 		ITC.Set("ic_stealth", "graph/interface/book/character_sheet/buttons_carac/icone_stealth");
4870 		ITC.Set("ic_strength", "graph/interface/book/character_sheet/buttons_carac/icone_strenght");
4871 
4872 		ITC.Set("questbook", "graph/interface/book/questbook");
4873 		ITC.Set("ptexspellbook", "graph/interface/book/spellbook");
4874 		ITC.Set("bookmark_char", "graph/interface/book/bookmark_char");
4875 		ITC.Set("bookmark_magic", "graph/interface/book/bookmark_magic");
4876 		ITC.Set("bookmark_map", "graph/interface/book/bookmark_map");
4877 		ITC.Set("bookmark_quest", "graph/interface/book/bookmark_quest");
4878 
4879 		ITC.Set("accessible_1", "graph/interface/book/accessible/accessible_1");
4880 		ITC.Set("accessible_2", "graph/interface/book/accessible/accessible_2");
4881 		ITC.Set("accessible_3", "graph/interface/book/accessible/accessible_3");
4882 		ITC.Set("accessible_4", "graph/interface/book/accessible/accessible_4");
4883 		ITC.Set("accessible_5", "graph/interface/book/accessible/accessible_5");
4884 		ITC.Set("accessible_6", "graph/interface/book/accessible/accessible_6");
4885 		ITC.Set("accessible_7", "graph/interface/book/accessible/accessible_7");
4886 		ITC.Set("accessible_8", "graph/interface/book/accessible/accessible_8");
4887 		ITC.Set("accessible_9", "graph/interface/book/accessible/accessible_9");
4888 		ITC.Set("accessible_10", "graph/interface/book/accessible/accessible_10");
4889 		ITC.Set("current_1", "graph/interface/book/current_page/current_1");
4890 		ITC.Set("current_2", "graph/interface/book/current_page/current_2");
4891 		ITC.Set("current_3", "graph/interface/book/current_page/current_3");
4892 		ITC.Set("current_4", "graph/interface/book/current_page/current_4");
4893 		ITC.Set("current_5", "graph/interface/book/current_page/current_5");
4894 		ITC.Set("current_6", "graph/interface/book/current_page/current_6");
4895 		ITC.Set("current_7", "graph/interface/book/current_page/current_7");
4896 		ITC.Set("current_8", "graph/interface/book/current_page/current_8");
4897 		ITC.Set("current_9", "graph/interface/book/current_page/current_9");
4898 		ITC.Set("current_10", "graph/interface/book/current_page/current_10");
4899 
4900 		ITC.Set("ptexcursorredist", "graph/interface/cursors/add_points");
4901 
4902 		ITC.Level = getLocalised("system_charsheet_player_lvl");
4903 		ITC.Xp = getLocalised("system_charsheet_player_xp");
4904 
4905 		ANIM_Set(&player.useanim,herowaitbook);
4906 
4907 		player.useanim.flags |= EA_LOOP;
4908 
4909 		ARXOldTimeMenu=ARXTimeMenu=arxtime.get_updated();
4910 		ARXDiffTimeMenu=0;
4911 	}
4912 
4913 	BOOKDECX = 0;
4914 	BOOKDECY = 0;
4915 
4916 	GRenderer->GetTextureStage(0)->SetMinFilter(TextureStage::FilterLinear);
4917 	GRenderer->GetTextureStage(0)->SetMagFilter(TextureStage::FilterLinear);
4918 
4919 	if(ARXmenu.currentmode != AMCM_NEWQUEST) {
4920 		switch(Book_Mode) {
4921 			case BOOKMODE_STATS: {
4922 				DrawBookInterfaceItem(ITC.Get("playerbook"), 97, 64, Color::white, 0.9999f);
4923 				break;
4924 			}
4925 			case BOOKMODE_SPELLS: {
4926 				DrawBookInterfaceItem(ITC.Get("ptexspellbook"), 97, 64, Color::white, 0.9999f);
4927 				break;
4928 			}
4929 			case BOOKMODE_MINIMAP: {
4930 				DrawBookInterfaceItem( ITC.Get("questbook"), 97, 64, Color::white, 0.9999f);
4931 				break;
4932 			}
4933 			case BOOKMODE_QUESTS: {
4934 				gui::manageQuestBook();
4935 				break;
4936 			}
4937 		}
4938 	}
4939 	else
4940 	{
4941 		float x = 0;
4942 
4943 		if ( ITC.Get("playerbook") )
4944 		{
4945 			x = static_cast<float>( ( 640 - ITC.Get("playerbook")->m_dwWidth ) / 2 );
4946 			float y = static_cast<float>( ( 480 - ITC.Get("playerbook")->m_dwHeight ) / 2 );
4947 
4948 			DrawBookInterfaceItem(ITC.Get("playerbook"), x, y);
4949 		}
4950 
4951 		BOOKDECX = x - 97;
4952 		BOOKDECY = x - 64 + 19;
4953 	}
4954 
4955 	if (ARXmenu.currentmode != AMCM_NEWQUEST)
4956 	{
4957 		bool bOnglet[11];
4958 		long max_onglet = 0;
4959 		long Book_Page = 1;
4960 
4961 		//---------------------------------------------------------------------
4962 		// Checks Clicks in bookmarks
4963 
4964 		// Character Sheet
4965 		if (Book_Mode != BOOKMODE_STATS)
4966 		{
4967 			float px=BOOKMARKS_POS_X;
4968 			float py=BOOKMARKS_POS_Y;
4969 			TextureContainer* tcBookmarkChar = ITC.Get("bookmark_char");
4970 			DrawBookInterfaceItem(tcBookmarkChar, px, py);
4971 
4972 			// Check for cursor on charcter sheet bookmark
4973 			if (	tcBookmarkChar
4974 				&&	MouseInBookRect(px,py,px+tcBookmarkChar->m_dwWidth,py+tcBookmarkChar->m_dwHeight))
4975 			{
4976 				// Draw highlighted Character sheet icon
4977 				GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
4978 				GRenderer->SetRenderState(Renderer::AlphaBlending, true);
4979 				DrawBookInterfaceItem(tcBookmarkChar, px, py, Color::grayb(0x55));
4980 				GRenderer->SetRenderState(Renderer::AlphaBlending, false);
4981 
4982 				// Set cursor to interacting
4983 				SpecialCursor=CURSOR_INTERACTION_ON;
4984 
4985 				// Check for click
4986 				if(bookclick.x != -1) {
4987 					ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
4988 					openBookPage(BOOKMODE_STATS);
4989 					pTextManage->Clear();
4990 				}
4991 			}
4992 		}
4993 
4994 		if (Book_Mode != BOOKMODE_SPELLS)
4995 		{
4996 			if (player.rune_flags)
4997 			{
4998 				float px=BOOKMARKS_POS_X+32;
4999 				float py=BOOKMARKS_POS_Y;
5000 				DrawBookInterfaceItem(ITC.Get("bookmark_magic"), px, py);
5001 
5002 				if(NewSpell == 1) {
5003 					NewSpell = 2;
5004 					for(long nk = 0; nk < 2; nk++) {
5005 						MagFX(Vec3f(BOOKDECX + 220.f, BOOKDECY + 49.f, 0.000001f));
5006 					}
5007 				}
5008 
5009 				if (	ITC.Get("bookmark_magic")
5010 					&&	MouseInBookRect(px,py,px+ITC.Get("bookmark_magic")->m_dwWidth,py+ITC.Get("bookmark_magic")->m_dwHeight))
5011 				{
5012 					// Draw highlighted Magic sheet icon
5013 					GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
5014 					GRenderer->SetRenderState(Renderer::AlphaBlending, true);
5015 					DrawBookInterfaceItem(ITC.Get("bookmark_magic"), px, py, Color::grayb(0x55));
5016 					GRenderer->SetRenderState(Renderer::AlphaBlending, false);
5017 
5018 					// Set cursor to interacting
5019 					SpecialCursor=CURSOR_INTERACTION_ON;
5020 
5021 					// Check for click
5022 					if(bookclick.x != -1) {
5023 						ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
5024 						openBookPage(BOOKMODE_SPELLS);
5025 						pTextManage->Clear();
5026 					}
5027 				}
5028 			}
5029 		}
5030 
5031 		if (Book_Mode != BOOKMODE_MINIMAP)
5032 		{
5033 			float px=BOOKMARKS_POS_X+64;
5034 			float py=BOOKMARKS_POS_Y;
5035 
5036 			DrawBookInterfaceItem(ITC.Get("bookmark_map"), px, py);
5037 
5038 			if (	ITC.Get("bookmark_map")
5039 				&&	MouseInBookRect(px,py,px+ITC.Get("bookmark_map")->m_dwWidth,py+ITC.Get("bookmark_map")->m_dwHeight))
5040 			{
5041 				GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
5042 				GRenderer->SetRenderState(Renderer::AlphaBlending, true);
5043 				DrawBookInterfaceItem(ITC.Get("bookmark_map"), px, py, Color::grayb(0x55));
5044 				GRenderer->SetRenderState(Renderer::AlphaBlending, false);
5045 
5046 				// Set cursor to interacting
5047 				SpecialCursor=CURSOR_INTERACTION_ON;
5048 
5049 				// Check for click
5050 				if(bookclick.x != -1) {
5051 					ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
5052 					openBookPage(BOOKMODE_MINIMAP);
5053 					pTextManage->Clear();
5054 				}
5055 			}
5056 		}
5057 
5058 		if (Book_Mode != BOOKMODE_QUESTS)
5059 		{
5060 			float px=BOOKMARKS_POS_X+96;
5061 			float py=BOOKMARKS_POS_Y;
5062 			DrawBookInterfaceItem(ITC.Get("bookmark_quest"), px, py);
5063 
5064 			if (	ITC.Get("bookmark_quest")
5065 				&&	MouseInBookRect(px,py,px+ITC.Get("bookmark_quest")->m_dwWidth,py+ITC.Get("bookmark_quest")->m_dwHeight))
5066 			{
5067 				GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
5068 				GRenderer->SetRenderState(Renderer::AlphaBlending, true);
5069 				DrawBookInterfaceItem(ITC.Get("bookmark_quest"), px, py, Color::grayb(0x55));
5070 				GRenderer->SetRenderState(Renderer::AlphaBlending, false);
5071 
5072 				// Set cursor to interacting
5073 				SpecialCursor=CURSOR_INTERACTION_ON;
5074 
5075 				// Check for click
5076 				if(bookclick.x != -1) {
5077 					ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
5078 					openBookPage(BOOKMODE_QUESTS);
5079 					pTextManage->Clear();
5080 				}
5081 			}
5082 		}
5083 
5084 		if (Book_Mode == BOOKMODE_MINIMAP) max_onglet=8;
5085 		else max_onglet=10;
5086 
5087 		if (Book_Mode == BOOKMODE_SPELLS) Book_Page = Book_SpellPage;
5088 		else Book_Page = Book_MapPage;
5089 
5090 		std::fill_n(bOnglet, 11, false);
5091 
5092 		// calcul de la page de spells
5093 		if (Book_Mode == BOOKMODE_SPELLS)
5094 		{
5095 			for (size_t i = 0; i < SPELL_COUNT; ++i)
5096 			{
5097 				if (spellicons[i].bSecret == false)
5098 				{
5099 					bool bOk = true;
5100 
5101 					for(long j = 0; j < 4 && spellicons[i].symbols[j] != RUNE_NONE; ++j) {
5102 						if(!(player.rune_flags & (RuneFlag)(1<<spellicons[i].symbols[j])))
5103 							bOk = false;
5104 					}
5105 
5106 					if (bOk)
5107 						bOnglet[spellicons[i].level] = true;
5108 				}
5109 			}
5110 		}
5111 		else
5112 		{
5113 			memset(bOnglet, true, (max_onglet + 1) * sizeof(*bOnglet));
5114 		}
5115 
5116 		if ((Book_Mode==BOOKMODE_SPELLS) || (Book_Mode==BOOKMODE_MINIMAP))
5117 		{
5118 			if (bOnglet[1])
5119 			{
5120 				if (Book_Page!=1)
5121 				{
5122 					float px=100.f;
5123 					float py=82.f;
5124 					DrawBookInterfaceItem(ITC.Get("accessible_1"), px, py);
5125 
5126 					if(MouseInBookRect(px, py, px + 32, py + 32)) {
5127 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
5128 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
5129 						DrawBookInterfaceItem(ITC.Get("accessible_1"), px, py, Color::grayb(0x55));
5130 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
5131 						SpecialCursor=CURSOR_INTERACTION_ON;
5132 
5133 						if (bookclick.x!=-1)
5134 						{
5135 							Book_Page=1;
5136 							ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
5137 						}
5138 					}
5139 				} else {
5140 					DrawBookInterfaceItem(ITC.Get("current_1"), 102.f, 82.f);
5141 				}
5142 			}
5143 
5144 			if (bOnglet[2])
5145 			{
5146 				if (Book_Page!=2)
5147 				{
5148 					float px=98.f;
5149 					float py=112.f;
5150 					DrawBookInterfaceItem(ITC.Get("accessible_2"), px, py);
5151 
5152 					if (MouseInBookRect(px,py,px+32,py+32))
5153 					{
5154 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
5155 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
5156 						DrawBookInterfaceItem(ITC.Get("accessible_2"), px, py, Color::grayb(0x55));
5157 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
5158 						SpecialCursor=CURSOR_INTERACTION_ON;
5159 
5160 						if (bookclick.x!=-1)
5161 						{
5162 							Book_Page=2;
5163 							ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
5164 						}
5165 					}
5166 				}
5167 				else DrawBookInterfaceItem(ITC.Get("current_2"), 100.f, 114.f);
5168 			}
5169 
5170 			if (bOnglet[3])
5171 			{
5172 				if (Book_Page!=3)
5173 				{
5174 					float px=97.f;
5175 					float py=143.f;
5176 					DrawBookInterfaceItem(ITC.Get("accessible_3"), px, py);
5177 
5178 					if(MouseInBookRect(px, py, px + 32, py + 32)) {
5179 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
5180 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
5181 						DrawBookInterfaceItem(ITC.Get("accessible_3"), px, py, Color::grayb(0x55));
5182 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
5183 						SpecialCursor=CURSOR_INTERACTION_ON;
5184 						if(bookclick.x != -1) {
5185 							Book_Page=3;
5186 							ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
5187 						}
5188 					}
5189 				}
5190 				else DrawBookInterfaceItem(ITC.Get("current_3"), 101.f, 141.f);
5191 			}
5192 
5193 			if (bOnglet[4])
5194 			{
5195 				if (Book_Page!=4)
5196 				{
5197 					float px=95.f;
5198 					float py=170.f;
5199 					DrawBookInterfaceItem(ITC.Get("accessible_4"), px, py);
5200 
5201 					if(MouseInBookRect(px, py, px + 32, py + 32)) {
5202 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
5203 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
5204 						DrawBookInterfaceItem(ITC.Get("accessible_4"), px, py, Color::grayb(0x55));
5205 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
5206 						SpecialCursor=CURSOR_INTERACTION_ON;
5207 						if(bookclick.x != -1) {
5208 							Book_Page=4;
5209 							ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
5210 						}
5211 					}
5212 				}
5213 				else DrawBookInterfaceItem(ITC.Get("current_4"), 100.f, 170.f);
5214 			}
5215 
5216 			if (bOnglet[5])
5217 			{
5218 				if (Book_Page!=5)
5219 				{
5220 					float px=95.f;
5221 					float py=200.f;
5222 					DrawBookInterfaceItem(ITC.Get("accessible_5"), px, py);
5223 
5224 					if(MouseInBookRect(px, py, px + 32, py + 32)) {
5225 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
5226 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
5227 						DrawBookInterfaceItem(ITC.Get("accessible_5"), px, py, Color::grayb(0x55));
5228 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
5229 						SpecialCursor=CURSOR_INTERACTION_ON;
5230 						if(bookclick.x != -1) {
5231 							Book_Page=5;
5232 							ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
5233 						}
5234 					}
5235 				}
5236 				else DrawBookInterfaceItem(ITC.Get("current_5"), 97.f, 199.f);
5237 			}
5238 
5239 			if (bOnglet[6])
5240 			{
5241 				if (Book_Page!=6)
5242 				{
5243 					float px=94.f;
5244 					float py=229.f;
5245 					DrawBookInterfaceItem(ITC.Get("accessible_6"), px, py);
5246 
5247 					if(MouseInBookRect(px, py, px + 32, py + 32)) {
5248 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
5249 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
5250 						DrawBookInterfaceItem(ITC.Get("accessible_6"), px, py, Color::grayb(0x55));
5251 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
5252 						SpecialCursor=CURSOR_INTERACTION_ON;
5253 						if(bookclick.x != -1) {
5254 							Book_Page=6;
5255 							ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
5256 						}
5257 					}
5258 				}
5259 				else DrawBookInterfaceItem(ITC.Get("current_6"), 103.f, 226.f);
5260 			}
5261 
5262 			if (bOnglet[7])
5263 			{
5264 				if (Book_Page!=7)
5265 				{
5266 					float px=94.f;
5267 					float py=259.f;
5268 					DrawBookInterfaceItem(ITC.Get("accessible_7"), px, py);
5269 
5270 					if(MouseInBookRect(px, py, px + 32, py + 32)) {
5271 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
5272 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
5273 						DrawBookInterfaceItem(ITC.Get("accessible_7"), px, py, Color::grayb(0x55));
5274 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
5275 						SpecialCursor=CURSOR_INTERACTION_ON;
5276 						if(bookclick.x != -1) {
5277 							Book_Page=7;
5278 							ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
5279 						}
5280 					}
5281 				}
5282 				else DrawBookInterfaceItem(ITC.Get("current_7"), 101.f, 255.f);
5283 			}
5284 
5285 			if (bOnglet[8])
5286 			{
5287 				if (Book_Page!=8)
5288 				{
5289 					float px=92.f;
5290 					float py=282.f;
5291 					DrawBookInterfaceItem(ITC.Get("accessible_8"), px, py);
5292 
5293 					if(MouseInBookRect(px, py, px + 32, py + 32)) {
5294 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
5295 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
5296 						DrawBookInterfaceItem(ITC.Get("accessible_8"), px, py, Color::grayb(0x55));
5297 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
5298 						SpecialCursor=CURSOR_INTERACTION_ON;
5299 						if(bookclick.x != -1) {
5300 							Book_Page=8;
5301 							ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
5302 						}
5303 					}
5304 				}
5305 				else DrawBookInterfaceItem(ITC.Get("current_8"), 99.f, 283.f);
5306 			}
5307 
5308 			if (bOnglet[9])
5309 			{
5310 				if (Book_Page!=9)
5311 				{
5312 					float px=90.f;
5313 					float py=308.f;
5314 					DrawBookInterfaceItem(ITC.Get("accessible_9"), px, py);
5315 
5316 					if(MouseInBookRect(px, py, px + 32, py + 32)) {
5317 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
5318 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
5319 						DrawBookInterfaceItem(ITC.Get("accessible_9"), px, py, Color::grayb(0x55));
5320 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
5321 						SpecialCursor=CURSOR_INTERACTION_ON;
5322 						if(bookclick.x != -1) {
5323 							Book_Page=9;
5324 							ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
5325 						}
5326 					}
5327 				}
5328 				else DrawBookInterfaceItem(ITC.Get("current_9"), 99.f, 307.f);
5329 			}
5330 
5331 			if (bOnglet[10])
5332 			{
5333 				if (Book_Page!=10)
5334 				{
5335 					float px=97.f;
5336 					float py=331.f;
5337 					DrawBookInterfaceItem(ITC.Get("accessible_10"), px, py);
5338 
5339 					if(MouseInBookRect(px, py, px + 32, py + 32)) {
5340 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
5341 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
5342 						DrawBookInterfaceItem(ITC.Get("accessible_10"), px, py, Color::grayb(0x55));
5343 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
5344 						SpecialCursor=CURSOR_INTERACTION_ON;
5345 						if(bookclick.x != -1) {
5346 							Book_Page=10;
5347 							ARX_SOUND_PlayInterface(SND_BOOK_PAGE_TURN, 0.9F + 0.2F * rnd());
5348 						}
5349 					}
5350 				}
5351 				else DrawBookInterfaceItem(ITC.Get("current_10"), 104.f, 331.f);
5352 			}
5353 
5354 			if(Book_Mode == BOOKMODE_SPELLS) {
5355 				Book_SpellPage = Book_Page;
5356 			} else if(Book_Mode == BOOKMODE_MINIMAP) {
5357 				Book_MapPage = Book_Page;
5358 			}
5359 		}
5360 
5361 		bookclick.x=-1;
5362 	}
5363 
5364 	GRenderer->GetTextureStage(0)->SetMinFilter(TextureStage::FilterNearest);
5365 	GRenderer->GetTextureStage(0)->SetMagFilter(TextureStage::FilterNearest);
5366 
5367 	if (Book_Mode == BOOKMODE_STATS)
5368 	{
5369 		FLYING_OVER = 0;
5370 		std::string tex;
5371 		Color color(0, 0, 0);
5372 
5373 		ARX_PLAYER_ComputePlayerFullStats();
5374 
5375 		std::stringstream ss;
5376 		ss << ITC.Level << " " << std::setw(3) << (int)player.level;
5377 		tex = ss.str();
5378 		DrawBookTextCenter(hFontInBook, 398, 74, tex, color);
5379 
5380 		std::stringstream ss2;
5381 		ss2 << ITC.Xp << " " << std::setw(8) << player.xp;
5382 		tex = ss2.str();
5383 		DrawBookTextCenter(hFontInBook, 510, 74, tex, color);
5384 
5385 		if (MouseInBookRect(463, 74, 550, 94))
5386 			FLYING_OVER = WND_XP;
5387 
5388 		if (MouseInBookRect(97+41,64+62, 97+41+32, 64+62+32))
5389 			FLYING_OVER = WND_AC;
5390 		else if (MouseInBookRect(97+41,64+120, 97+41+32, 64+120+32))
5391 			FLYING_OVER = WND_RESIST_MAGIC;
5392 		else if (MouseInBookRect(97+41,64+178, 97+41+32, 64+178+32))
5393 			FLYING_OVER = WND_RESIST_POISON;
5394 		else if (MouseInBookRect(97+211,64+62, 97+211+32, 64+62+32))
5395 			FLYING_OVER = WND_HP;
5396 		else if (MouseInBookRect(97+211,64+120, 97+211+32, 64+120+32))
5397 			FLYING_OVER = WND_MANA;
5398 		else if (MouseInBookRect(97+211,64+178, 97+211+32, 64+178+32))
5399 			FLYING_OVER = WND_DAMAGE;
5400 
5401 		if (!((player.Attribute_Redistribute == 0) && (ARXmenu.currentmode != AMCM_NEWQUEST)))
5402 		{
5403 			// Main Player Attributes
5404 			if (CheckAttributeClick(379,95,&player.Attribute_Strength,		ITC.Get("ic_strength")))
5405 			{
5406 				FLYING_OVER=BOOK_STRENGTH;
5407 				SpecialCursor = CURSOR_REDIST;
5408 				lCursorRedistValue = player.Attribute_Redistribute;
5409 			}
5410 
5411 			if (CheckAttributeClick(428,95,&player.Attribute_Mind,			ITC.Get("ic_mind")))
5412 			{
5413 				FLYING_OVER=BOOK_MIND;
5414 				SpecialCursor = CURSOR_REDIST;
5415 				lCursorRedistValue = player.Attribute_Redistribute;
5416 			}
5417 
5418 			if (CheckAttributeClick(477,95,&player.Attribute_Dexterity,		ITC.Get("ic_dexterity")))
5419 			{
5420 				FLYING_OVER=BOOK_DEXTERITY;
5421 				SpecialCursor = CURSOR_REDIST;
5422 				lCursorRedistValue = player.Attribute_Redistribute;
5423 			}
5424 
5425 			if (CheckAttributeClick(526,95,&player.Attribute_Constitution,	ITC.Get("ic_constitution")))
5426 			{
5427 				FLYING_OVER=BOOK_CONSTITUTION;
5428 				SpecialCursor = CURSOR_REDIST;
5429 				lCursorRedistValue = player.Attribute_Redistribute;
5430 			}
5431 		}
5432 
5433 		if (!((player.Skill_Redistribute == 0) && (ARXmenu.currentmode != AMCM_NEWQUEST)))
5434 		{
5435 			if (CheckSkillClick(389,177,&player.Skill_Stealth,		ITC.Get("ic_stealth"),&player.Old_Skill_Stealth))
5436 			{
5437 				FLYING_OVER=BOOK_STEALTH;
5438 				SpecialCursor = CURSOR_REDIST;
5439 				lCursorRedistValue = player.Skill_Redistribute;
5440 			}
5441 
5442 			if (CheckSkillClick(453,177,&player.Skill_Mecanism,		ITC.Get("ic_mecanism"),&player.Old_Skill_Mecanism))
5443 			{
5444 				FLYING_OVER=BOOK_MECANISM;
5445 				SpecialCursor = CURSOR_REDIST;
5446 				lCursorRedistValue = player.Skill_Redistribute;
5447 			}
5448 
5449 			if (CheckSkillClick(516,177,&player.Skill_Intuition,	ITC.Get("ic_intuition"),&player.Old_Skill_Intuition))
5450 			{
5451 				FLYING_OVER=BOOK_INTUITION;
5452 				SpecialCursor = CURSOR_REDIST;
5453 				lCursorRedistValue = player.Skill_Redistribute;
5454 			}
5455 
5456 			if (CheckSkillClick(389,230,&player.Skill_Etheral_Link,	ITC.Get("ic_etheral_link"),&player.Old_Skill_Etheral_Link))
5457 			{
5458 				FLYING_OVER=BOOK_ETHERAL_LINK;
5459 				SpecialCursor = CURSOR_REDIST;
5460 				lCursorRedistValue = player.Skill_Redistribute;
5461 			}
5462 
5463 			if (CheckSkillClick(453,230,&player.Skill_Object_Knowledge,ITC.Get("ic_object_knowledge"),&player.Old_Skill_Object_Knowledge))
5464 			{
5465 				FLYING_OVER=BOOK_OBJECT_KNOWLEDGE;
5466 				SpecialCursor = CURSOR_REDIST;
5467 				lCursorRedistValue = player.Skill_Redistribute;
5468 
5469 				if ((BOOKBUTTON & 1) && !(LASTBOOKBUTTON & 1))
5470 				{
5471 					ARX_INVENTORY_IdentifyAll();
5472 					ARX_EQUIPMENT_IdentifyAll();
5473 				}
5474 
5475 				ARX_PLAYER_ComputePlayerFullStats();
5476 			}
5477 
5478 			if (CheckSkillClick(516,230,&player.Skill_Casting,		ITC.Get("ic_casting"),&player.Old_Skill_Casting))
5479 			{
5480 				FLYING_OVER=BOOK_CASTING;
5481 				SpecialCursor = CURSOR_REDIST;
5482 				lCursorRedistValue = player.Skill_Redistribute;
5483 			}
5484 
5485 			if (CheckSkillClick(389,284,&player.Skill_Close_Combat,	ITC.Get("ic_close_combat"),&player.Old_Skill_Close_Combat))
5486 			{
5487 				FLYING_OVER=BOOK_CLOSE_COMBAT;
5488 				SpecialCursor = CURSOR_REDIST;
5489 				lCursorRedistValue = player.Skill_Redistribute;
5490 			}
5491 
5492 			if (CheckSkillClick(453,284,&player.Skill_Projectile,	ITC.Get("ic_projectile"),&player.Old_Skill_Projectile))
5493 			{
5494 				FLYING_OVER=BOOK_PROJECTILE;
5495 				SpecialCursor = CURSOR_REDIST;
5496 				lCursorRedistValue = player.Skill_Redistribute;
5497 			}
5498 
5499 			if (CheckSkillClick(516,284,&player.Skill_Defense,		ITC.Get("ic_defense"),&player.Old_Skill_Defense))
5500 			{
5501 				FLYING_OVER=BOOK_DEFENSE;
5502 				SpecialCursor = CURSOR_REDIST;
5503 				lCursorRedistValue = player.Skill_Redistribute;
5504 			}
5505 		}
5506 		else
5507 		{
5508 			//------------------------------------PRIMARY
5509 			if (MouseInBookRect(379,95, 379+32, 95+32))
5510 				FLYING_OVER=BOOK_STRENGTH;
5511 			else if (MouseInBookRect(428,95, 428+32, 95+32))
5512 				FLYING_OVER=BOOK_MIND;
5513 			else if (MouseInBookRect(477,95, 477+32, 95+32))
5514 				FLYING_OVER=BOOK_DEXTERITY;
5515 			else if (MouseInBookRect(526,95, 526+32, 95+32))
5516 				FLYING_OVER=BOOK_CONSTITUTION;
5517 
5518 			//------------------------------------SECONDARY
5519 			if (MouseInBookRect(389,177, 389+32, 177+32))
5520 				FLYING_OVER=BOOK_STEALTH;
5521 			else if (MouseInBookRect(453,177, 453+32, 177+32))
5522 				FLYING_OVER=BOOK_MECANISM;
5523 			else if (MouseInBookRect(516,177, 516+32, 177+32))
5524 				FLYING_OVER=BOOK_INTUITION;
5525 			else if (MouseInBookRect(389,230, 389+32, 230+32))
5526 				FLYING_OVER=BOOK_ETHERAL_LINK;
5527 			else if (MouseInBookRect(453,230, 453+32, 230+32))
5528 				FLYING_OVER=BOOK_OBJECT_KNOWLEDGE;
5529 			else if (MouseInBookRect(516,230, 516+32, 230+32))
5530 				FLYING_OVER=BOOK_CASTING;
5531 			else if (MouseInBookRect(389,284, 389+32, 284+32))
5532 				FLYING_OVER=BOOK_CLOSE_COMBAT;
5533 			else if (MouseInBookRect(453,284, 453+32, 284+32))
5534 				FLYING_OVER=BOOK_PROJECTILE;
5535 			else if (MouseInBookRect(516,284, 516+32, 284+32))
5536 				FLYING_OVER=BOOK_DEFENSE;
5537 		}
5538 
5539 		//------------------------------ SEB 04/12/2001
5540 		if (ARXmenu.mda && !ARXmenu.mda->flyover[FLYING_OVER].empty()) //=ARXmenu.mda->flyover[FLYING_OVER];
5541 		{
5542 			float fRandom = rnd() * 2;
5543 
5544 			int t = checked_range_cast<int>(fRandom);
5545 
5546 			pTextManage->Clear();
5547 			OLD_FLYING_OVER=FLYING_OVER;
5548 
5549 			// Nuky Note: the text used never scrolls, centered function with wordwrap would be enough
5550 			if (FLYING_OVER == WND_XP)
5551 			{
5552 				std::stringstream ss;
5553 				ss << ARXmenu.mda->flyover[WND_XP] << " " << std::setw(8) << GetXPforLevel(player.level+1)-player.xp;
5554 				UNICODE_ARXDrawTextCenteredScroll( hFontInGame,
5555 					                                (DANAESIZX*0.5f),
5556 					                                4,
5557 					                                (DANAECENTERX)*0.82f,
5558 					                                ss.str(),
5559 					                                Color(232+t,204+t,143+t),
5560 					                                1000,
5561 					                                0.01f,
5562 					                                3,
5563 					                                0);
5564 			}
5565 			else
5566 			{
5567 				UNICODE_ARXDrawTextCenteredScroll(hFontInGame,
5568 					(DANAESIZX*0.5f),
5569 					4,
5570 					(DANAECENTERX)*0.82f,
5571 					ARXmenu.mda->flyover[FLYING_OVER],
5572 					Color(232+t,204+t,143+t),
5573 					1000,
5574 					0.01f,
5575 					3,
5576 					0);
5577 			}
5578 		}
5579 		else
5580 		{
5581 			OLD_FLYING_OVER=-1;
5582 		}
5583 
5584 		//------------------------------
5585 
5586 		std::stringstream ss3;
5587 		ss3 << std::setw(3) << std::setprecision(0) << std::fixed << player.Full_Attribute_Strength;
5588 		tex = ss3.str();
5589 
5590 		if (player.Mod_Attribute_Strength<0.f)
5591 			color = Color::red;
5592 		else if (player.Mod_Attribute_Strength>0.f)
5593 			color = Color::blue;
5594 		else color = Color::black;
5595 
5596 		if (ARXmenu.currentmode==AMCM_NEWQUEST)
5597 		{
5598 			if (player.Full_Attribute_Strength == 6)
5599 				color = Color::red;
5600 		}
5601 
5602 		DrawBookTextCenter(hFontInBook, 391, 129, tex, color);
5603 
5604 		ss3.str(""); // clear the stream
5605 		ss3 << player.Full_Attribute_Mind;
5606 		tex = ss3.str();
5607 
5608 		if (player.Mod_Attribute_Mind<0.f)
5609 			color = Color::red;
5610 		else if (player.Mod_Attribute_Mind>0.f)
5611 			color = Color::blue;
5612 		else color = Color::black;
5613 
5614 		if (ARXmenu.currentmode==AMCM_NEWQUEST)
5615 		{
5616 			if (player.Full_Attribute_Mind == 6)
5617 				color = Color::red;
5618 		}
5619 
5620 		DrawBookTextCenter(hFontInBook, 440, 129, tex, color);
5621 
5622 		ss3.str("");
5623 		ss3 << player.Full_Attribute_Dexterity;
5624 		tex = ss3.str();
5625 
5626 		if (player.Mod_Attribute_Dexterity<0.f)
5627 			color = Color::red;
5628 		else if (player.Mod_Attribute_Dexterity>0.f)
5629 			color = Color::blue;
5630 		else color = Color::black;
5631 
5632 		if (ARXmenu.currentmode==AMCM_NEWQUEST)
5633 		{
5634 			if (player.Full_Attribute_Dexterity == 6)
5635 				color = Color::red;
5636 		}
5637 
5638 		DrawBookTextCenter(hFontInBook, 490, 129, tex, color);
5639 		ss3.str("");
5640 		ss3 << player.Full_Attribute_Constitution;
5641 		tex = ss3.str();
5642 
5643 		if (player.Mod_Attribute_Constitution<0.f)
5644 			color = Color::red;
5645 		else if (player.Mod_Attribute_Constitution>0.f)
5646 			color = Color::blue;
5647 		else color = Color::black;
5648 
5649 		if (ARXmenu.currentmode==AMCM_NEWQUEST)
5650 		{
5651 			if (player.Full_Attribute_Constitution == 6)
5652 				color = Color::red;
5653 		}
5654 
5655 		DrawBookTextCenter(hFontInBook, 538, 129, tex, color);
5656 
5657 		// Player Skills
5658 		ss3.str("");
5659 		ss3 << player.Full_Skill_Stealth;
5660 		tex = ss3.str();
5661 
5662 		if (player.Mod_Skill_Stealth<0.f)
5663 			color = Color::red;
5664 		else if (player.Mod_Skill_Stealth>0.f)
5665 			color = Color::blue;
5666 		else color = Color::black;
5667 
5668 		if (ARXmenu.currentmode==AMCM_NEWQUEST)
5669 		{
5670 			if (player.Skill_Stealth == 0)
5671 				color = Color::red;
5672 		}
5673 
5674 		DrawBookTextCenter(hFontInBook, 405, 210, tex, color);
5675 
5676 		ss3.str("");
5677 		ss3 << player.Full_Skill_Mecanism;
5678 		tex = ss3.str();
5679 
5680 		if (player.Mod_Skill_Mecanism<0.f)
5681 			color = Color::red;
5682 		else if (player.Mod_Skill_Mecanism>0.f)
5683 			color = Color::blue;
5684 		else color = Color::black;
5685 
5686 		if (ARXmenu.currentmode==AMCM_NEWQUEST)
5687 		{
5688 			if (player.Skill_Mecanism == 0)
5689 				color = Color::red;
5690 		}
5691 
5692 		DrawBookTextCenter(hFontInBook, 469, 210, tex, color);
5693 
5694 		ss3.str("");
5695 		ss3 << player.Full_Skill_Intuition;
5696 		tex = ss3.str();
5697 
5698 		if (player.Mod_Skill_Intuition<0.f)
5699 			color = Color::red;
5700 		else if (player.Mod_Skill_Intuition>0.f)
5701 			color = Color::blue;
5702 		else color = Color::black;
5703 
5704 		if (ARXmenu.currentmode==AMCM_NEWQUEST)
5705 		{
5706 			if (player.Skill_Intuition == 0)
5707 				color = Color::red;
5708 		}
5709 
5710 		DrawBookTextCenter(hFontInBook, 533, 210, tex, color);
5711 
5712 		ss3.str("");
5713 		ss3 << player.Full_Skill_Etheral_Link;
5714 		tex = ss3.str();
5715 
5716 		if (player.Mod_Skill_Etheral_Link<0.f)
5717 			color = Color::red;
5718 		else if (player.Mod_Skill_Etheral_Link>0.f)
5719 			color = Color::blue;
5720 		else color = Color::black;
5721 
5722 		if (ARXmenu.currentmode==AMCM_NEWQUEST)
5723 		{
5724 			if (player.Skill_Etheral_Link == 0)
5725 				color = Color::red;
5726 		}
5727 
5728 		DrawBookTextCenter(hFontInBook, 405, 265, tex, color);
5729 
5730 		ss3.str("");
5731 		ss3 << player.Full_Skill_Object_Knowledge;
5732 		tex = ss3.str();
5733 
5734 		if (player.Mod_Skill_Object_Knowledge<0.f)
5735 			color = Color::red;
5736 		else if (player.Mod_Skill_Object_Knowledge>0.f)
5737 			color = Color::blue;
5738 		else color = Color::black;
5739 
5740 		if (ARXmenu.currentmode==AMCM_NEWQUEST)
5741 		{
5742 			if (player.Skill_Object_Knowledge == 0)
5743 				color = Color::red;
5744 		}
5745 
5746 		DrawBookTextCenter(hFontInBook, 469, 265, tex, color);
5747 
5748 		ss3.str("");
5749 		ss3 << player.Full_Skill_Casting;
5750 		tex = ss3.str();
5751 
5752 		if (player.Mod_Skill_Casting<0.f)
5753 			color = Color::red;
5754 		else if (player.Mod_Skill_Casting>0.f)
5755 			color = Color::blue;
5756 		else color = Color::black;
5757 
5758 		if (ARXmenu.currentmode==AMCM_NEWQUEST)
5759 		{
5760 			if (player.Skill_Casting == 0)
5761 				color = Color::red;
5762 		}
5763 
5764 		DrawBookTextCenter(hFontInBook, 533, 265, tex, color);
5765 
5766 		ss3.str("");
5767 		ss3 << player.Full_Skill_Close_Combat;
5768 		tex = ss3.str();
5769 
5770 		if (player.Mod_Skill_Close_Combat<0.f)
5771 			color = Color::red;
5772 		else if (player.Mod_Skill_Close_Combat>0.f)
5773 			color = Color::blue;
5774 		else color = Color::black;
5775 
5776 		if (ARXmenu.currentmode==AMCM_NEWQUEST)
5777 		{
5778 			if (player.Skill_Close_Combat == 0)
5779 				color = Color::red;
5780 		}
5781 
5782 		DrawBookTextCenter(hFontInBook, 405, 319, tex, color);
5783 
5784 
5785 		ss3.str("");
5786 		ss3 << player.Full_Skill_Projectile;
5787 		tex = ss3.str();
5788 
5789 		if (player.Mod_Skill_Projectile<0.f)
5790 			color = Color::red;
5791 		else if (player.Mod_Skill_Projectile>0.f)
5792 			color = Color::blue;
5793 		else color = Color::black;
5794 
5795 		if (ARXmenu.currentmode==AMCM_NEWQUEST)
5796 		{
5797 			if (player.Skill_Projectile == 0)
5798 				color = Color::red;
5799 		}
5800 
5801 		DrawBookTextCenter(hFontInBook, 469, 319, tex, color);
5802 
5803 		ss3.str("");
5804 		ss3 << player.Full_Skill_Defense;
5805 		tex = ss3.str();
5806 
5807 		if (player.Mod_Skill_Defense<0.f)
5808 			color = Color::red;
5809 		else if (player.Mod_Skill_Defense>0.f)
5810 			color = Color::blue;
5811 		else color = Color::black;
5812 
5813 		if (ARXmenu.currentmode==AMCM_NEWQUEST)
5814 		{
5815 			if (player.Skill_Defense == 0)
5816 				color = Color::red;
5817 		}
5818 
5819 		DrawBookTextCenter(hFontInBook, 533, 319, tex, color);
5820 
5821 		// Secondary Attributes
5822 		std::stringstream ss4;
5823 		ss4.str("");
5824 		ss4 << F2L_RoundUp(player.Full_maxlife);
5825 		tex = ss4.str();
5826 
5827 		if(player.Full_maxlife < player.maxlife) {
5828 			color = Color::red;
5829 		} else if(player.Full_maxlife > player.maxlife) {
5830 			color = Color::blue;
5831 		} else {
5832 			color = Color::black;
5833 		}
5834 
5835 		DrawBookTextCenter( hFontInBook, 324, 158, tex, color );
5836 
5837 		ss4.str("");
5838 		ss4 << F2L_RoundUp(player.Full_maxmana);
5839 		tex = ss4.str();
5840 
5841 		if(player.Full_maxmana < player.maxmana) {
5842 			color = Color::red;
5843 		} else if(player.Full_maxmana > player.maxmana) {
5844 			color = Color::blue;
5845 		} else {
5846 			color = Color::black;
5847 		}
5848 
5849 		DrawBookTextCenter( hFontInBook, 324, 218, tex, color );
5850 
5851 		ss4.str("");
5852 		ss4 << F2L_RoundUp(player.Full_damages);
5853 		tex = ss4.str();
5854 
5855 		if (player.Mod_damages<0.f)
5856 			color = Color::red;
5857 		else if (player.Mod_damages>0.f)
5858 			color = Color::blue;
5859 		else color = Color::black;
5860 
5861 		DrawBookTextCenter(hFontInBook, 324, 278, tex, color);
5862 
5863 		float ac = player.Full_armor_class;
5864 		ss4.str("");
5865 		ss4 << F2L_RoundUp(ac);
5866 		tex = ss4.str();
5867 
5868 		if (player.Mod_armor_class<0.f)
5869 			color = Color::red;
5870 		else if (player.Mod_armor_class>0.f)
5871 			color = Color::blue;
5872 		else color = Color::black;
5873 
5874 		DrawBookTextCenter(hFontInBook, 153, 158, tex, color);
5875 
5876 		ss4.str("");
5877 		ss4 << std::setw(3) << std::setprecision(0) << F2L_RoundUp( player.Full_resist_magic );
5878 		tex = ss4.str();
5879 
5880 		if (player.Mod_resist_magic<0.f)
5881 			color = Color::red;
5882 		else if (player.Mod_resist_magic>0.f)
5883 			color = Color::blue;
5884 		else color = Color::black;
5885 
5886 		DrawBookTextCenter(hFontInBook, 153, 218, tex, color);
5887 
5888 		ss4.str("");
5889 		ss4 << F2L_RoundUp( player.Full_resist_poison );
5890 		tex = ss4.str();
5891 
5892 		if (player.Mod_resist_poison<0.f)
5893 			color = Color::red;
5894 		else if (player.Mod_resist_poison>0.f)
5895 			color = Color::blue;
5896 		else color = Color::black;
5897 
5898 		DrawBookTextCenter(hFontInBook, 153, 278, tex, color);
5899 	}
5900 	else if (Book_Mode == BOOKMODE_MINIMAP)
5901 	{
5902 		long SHOWLEVEL = Book_MapPage - 1;
5903 
5904 		if (SHOWLEVEL >= 0 && SHOWLEVEL < 32)
5905 			g_miniMap.showBookEntireMap(SHOWLEVEL);
5906 
5907 		SHOWLEVEL = ARX_LEVELS_GetRealNum(CURRENTLEVEL);
5908 
5909 		if (SHOWLEVEL >= 0 && SHOWLEVEL < 32)
5910 			g_miniMap.showBookMiniMap(SHOWLEVEL);
5911 
5912 	}
5913 
5914 	if ((Book_Mode == BOOKMODE_STATS) && (entities.player()->obj != NULL))
5915 	{
5916 
5917 		GRenderer->SetRenderState(Renderer::DepthWrite, true);
5918 
5919 		Rect rec;
5920 		if (BOOKZOOM) {
5921 
5922 			rec = Rect(s32((120.f + BOOKDECX) * Xratio), s32((69.f + BOOKDECY) * Yratio),
5923 			           s32((330.f + BOOKDECX) * Xratio), s32((300.f + BOOKDECY) * Yratio));
5924 			GRenderer->Clear(Renderer::DepthBuffer, Color::none, 1.f, 1, &rec);
5925 
5926 			if(ARXmenu.currentmode != AMCM_OFF) {
5927 				Rect vp = Rect(Vec2i(s32(139.f * Xratio), 0), s32(139.f * Xratio), s32(310.f * Yratio));
5928 				GRenderer->SetViewport(vp);
5929 			}
5930 		} else {
5931 
5932 			rec = Rect(s32((118.f + BOOKDECX) * Xratio), s32((69.f + BOOKDECY) * Yratio),
5933 			          s32((350.f + BOOKDECX) * Xratio), s32((338.f + BOOKDECY) * Yratio));
5934 			GRenderer->Clear(Renderer::DepthBuffer, Color::none, 1.f, 1, &rec);
5935 
5936 			rec.right -= 50;
5937 		}
5938 
5939 		if (ARXmenu.currentmode==AMCM_OFF)
5940 			BOOKZOOM=0;
5941 
5942 		Vec3f pos;
5943 		EERIE_LIGHT eLight1;
5944 		EERIE_LIGHT eLight2;
5945 
5946 		eLight1.pos = Vec3f(50.f, 50.f, 200.f);
5947 		eLight1.exist = 1;
5948 		eLight1.rgb = Color3f(0.15f, 0.06f, 0.003f);
5949 		eLight1.intensity = 8.8f;
5950 		eLight1.fallstart = 2020;
5951 		eLight1.fallend = eLight1.fallstart + 60;
5952 		eLight1.rgb255 = eLight1.rgb * 255.f;
5953 		eLight1.falldiff = eLight1.fallend - eLight1.fallstart;
5954 		eLight1.falldiffmul = 1.f / eLight1.falldiff;
5955 		eLight1.precalc = eLight1.intensity * GLOBAL_LIGHT_FACTOR;
5956 
5957 		eLight2.exist = 1;
5958 		eLight2.pos = Vec3f(-50.f, -50.f, -200.f);
5959 		eLight2.rgb = Color3f::gray(0.6f);
5960 		eLight2.intensity=3.8f;
5961 		eLight2.fallstart = 0;
5962 		eLight2.fallend = eLight2.fallstart + 3460.f;
5963 		eLight2.rgb255 = eLight2.rgb * 255.f;
5964 		eLight2.falldiff = eLight2.fallend - eLight2.fallstart;
5965 		eLight2.falldiffmul = 1.f / eLight2.falldiff;
5966 		eLight2.precalc = eLight2.intensity * GLOBAL_LIGHT_FACTOR;
5967 
5968 		EERIE_LIGHT * SavePDL[2];
5969 		SavePDL[0]=PDL[0];
5970 		SavePDL[1]=PDL[1];
5971 		int			iSavePDL=TOTPDL;
5972 
5973 		PDL[0] = &eLight1;
5974 		PDL[1] = &eLight2;
5975 		TOTPDL = 2;
5976 
5977 		EERIE_CAMERA * oldcam = ACTIVECAM;
5978 		bookcam.center = rec.center();
5979 		SetActiveCamera(&bookcam);
5980 		PrepareCamera(&bookcam);
5981 
5982 		if(BOOKZOOM) {
5983 			Rect vp;
5984 			vp.left = static_cast<int>(rec.left + 52.f * Xratio);
5985 			vp.top = rec.top;
5986 			vp.right = static_cast<int>(rec.right - 21.f * Xratio);
5987 			vp.bottom = static_cast<int>(rec.bottom - 17.f * Yratio);
5988 			GRenderer->SetViewport(vp);
5989 		} else {
5990 			GRenderer->SetViewport(rec);
5991 		}
5992 
5993 		ePlayerAngle.a=0.f;
5994 		ePlayerAngle.g=0.f;
5995 
5996 		if (BOOKZOOM)
5997 		{
5998 			pos.x=8;
5999 			pos.y=162.f;
6000 			pos.z=75.f;
6001 			eLight1.pos.z=-90.f;
6002 		}
6003 		else
6004 		{
6005 			ePlayerAngle.b=-20.f;
6006 			pos.x=20.f;
6007 			pos.y=96.f;
6008 			pos.z=260.f;
6009 		}
6010 
6011 		if (!BOOKZOOM)
6012 			ARX_EQUIPMENT_AttachPlayerWeaponToHand();
6013 
6014 		long ti=Project.improve;
6015 		Project.improve=0;
6016 
6017 		if (entities.player()->invisibility>0.f)
6018 		{
6019 			GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
6020 			GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6021 		}
6022 
6023 		INVISIBILITY_OVERRIDE=entities.player()->invisibility;
6024 
6025 		if (INVISIBILITY_OVERRIDE>0.5f)
6026 			INVISIBILITY_OVERRIDE=0.5f;
6027 
6028 		FORCE_NO_HIDE=1;
6029 		IN_BOOK_DRAW=1;
6030 		std::vector<EERIE_VERTEX> vertexlist = entities.player()->obj->vertexlist3;
6031 
6032 		if(player.useanim.cur_anim != NULL) {
6033 			EERIEDrawAnimQuat(entities.player()->obj, &player.useanim, &ePlayerAngle, &pos,
6034 			                  checked_range_cast<unsigned long>(Original_framedelay), NULL);
6035 		} else {
6036 			DrawEERIEInter(entities.player()->obj, &ePlayerAngle, &pos, NULL);
6037 		}
6038 
6039 		INVISIBILITY_OVERRIDE=0;
6040 		IN_BOOK_DRAW=0;
6041 
6042 		if(ARXmenu.currentmode == AMCM_NEWQUEST) {
6043 			GRenderer->SetRenderState(Renderer::DepthTest, true);
6044 			GRenderer->GetTextureStage(0)->SetMipFilter(TextureStage::FilterNone);
6045 			GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6046 			PopAllTriangleList();
6047 			GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6048 			PopAllTriangleListTransparency();
6049 			GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6050 			GRenderer->GetTextureStage(0)->SetMipFilter(TextureStage::FilterLinear);
6051 			GRenderer->SetRenderState(Renderer::DepthTest, false);
6052 		}
6053 
6054 		PDL[0]=SavePDL[0];
6055 		PDL[1]=SavePDL[1];
6056 		TOTPDL=iSavePDL;
6057 
6058 		entities.player()->obj->vertexlist3 = vertexlist;
6059 		vertexlist.clear();
6060 		FORCE_NO_HIDE=0;
6061 		Project.improve=ti;
6062 
6063 		GRenderer->SetViewport(Rect(DANAESIZX, DANAESIZY));
6064 
6065 		GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6066 		GRenderer->SetCulling(Renderer::CullNone);
6067 		SetActiveCamera(oldcam);
6068 
6069 		Entity * io=entities.player();
6070 
6071 		if (io)
6072 		{
6073 			player.useanim.cur_anim = herowaitbook;
6074 
6075 			if (	(player.equiped[EQUIP_SLOT_WEAPON]!=0)
6076 				&&	ValidIONum(player.equiped[EQUIP_SLOT_WEAPON]	))
6077 			{
6078 				if (entities[player.equiped[EQUIP_SLOT_WEAPON]]->type_flags & OBJECT_TYPE_2H)
6079 				{
6080 					player.useanim.cur_anim = herowait_2h;
6081 				}
6082 			}
6083 
6084 			GRenderer->SetCulling(Renderer::CullNone);
6085 
6086 			if (	(player.equiped[EQUIP_SLOT_ARMOR]!=0)
6087 				&&	ValidIONum(player.equiped[EQUIP_SLOT_ARMOR]	))
6088 			{
6089 				Entity * tod=entities[player.equiped[EQUIP_SLOT_ARMOR]];
6090 
6091 				if (tod)
6092 				{
6093 
6094 
6095 					tod->bbox1.x = 195;
6096 					tod->bbox1.y = 116;
6097 					tod->bbox2.x = 284;
6098 					tod->bbox2.y = 182;
6099 
6100 					float fX1 = (tod->bbox1.x+BOOKDECX) * Xratio ;
6101 					float fX2 = (tod->bbox2.x+BOOKDECX) * Xratio ;
6102 					float fY1 = (tod->bbox1.y+BOOKDECY) * Yratio ;
6103 					float fY2 = (tod->bbox2.y+BOOKDECY) * Yratio ;
6104 
6105 					tod->bbox1.x = checked_range_cast<short>(fX1);
6106 					tod->bbox2.x = checked_range_cast<short>(fX2);
6107 					tod->bbox1.y = checked_range_cast<short>(fY1);
6108 					tod->bbox2.y = checked_range_cast<short>(fY2);
6109 
6110 					tod->ioflags |= IO_ICONIC;
6111 				}
6112 			}
6113 
6114 			if (	(player.equiped[EQUIP_SLOT_LEGGINGS]!=0)
6115 				&&	ValidIONum(player.equiped[EQUIP_SLOT_LEGGINGS]	))
6116 			{
6117 				Entity * tod=entities[player.equiped[EQUIP_SLOT_LEGGINGS]];
6118 
6119 				if (tod)
6120 				{
6121 
6122 
6123 					tod->bbox1.x = 218;
6124 					tod->bbox1.y = 183;
6125 					tod->bbox2.x = 277;
6126 					tod->bbox2.y = 322;
6127 
6128 					float fX1 = (tod->bbox1.x+BOOKDECX) * Xratio ;
6129 					float fX2 = (tod->bbox2.x+BOOKDECX) * Xratio ;
6130 					float fY1 = (tod->bbox1.y+BOOKDECY) * Yratio ;
6131 					float fY2 = (tod->bbox2.y+BOOKDECY) * Yratio ;
6132 
6133 					tod->bbox1.x = checked_range_cast<short>(fX1);
6134 					tod->bbox2.x = checked_range_cast<short>(fX2);
6135 					tod->bbox1.y = checked_range_cast<short>(fY1);
6136 					tod->bbox2.y = checked_range_cast<short>(fY2);
6137 
6138 					tod->ioflags|=IO_ICONIC;
6139 				}
6140 			}
6141 
6142 			if (	(player.equiped[EQUIP_SLOT_HELMET]!=0)
6143 				&&	ValidIONum(player.equiped[EQUIP_SLOT_HELMET]	))
6144 			{
6145 				Entity * tod=entities[player.equiped[EQUIP_SLOT_HELMET]];
6146 
6147 				if (tod)
6148 				{
6149 
6150 
6151 					tod->bbox1.x = 218;
6152 					tod->bbox1.y = 75;
6153 					tod->bbox2.x = 260;
6154 					tod->bbox2.y = 115;
6155 
6156 					float fX1 = (tod->bbox1.x+BOOKDECX) * Xratio ;
6157 					float fX2 = (tod->bbox2.x+BOOKDECX) * Xratio ;
6158 					float fY1 = (tod->bbox1.y+BOOKDECY) * Yratio ;
6159 					float fY2 = (tod->bbox2.y+BOOKDECY) * Yratio ;
6160 
6161 					tod->bbox1.x = checked_range_cast<short>(fX1);
6162 					tod->bbox2.x = checked_range_cast<short>(fX2);
6163 					tod->bbox1.y = checked_range_cast<short>(fY1);
6164 					tod->bbox2.y = checked_range_cast<short>(fY2);
6165 
6166 					tod->ioflags |= IO_ICONIC;
6167 				}
6168 			}
6169 
6170 			TextureContainer * tc;
6171 			TextureContainer * tc2=NULL;
6172 			GRenderer->SetCulling(Renderer::CullNone);
6173 
6174 			if (	(player.equiped[EQUIP_SLOT_RING_LEFT]!=0)
6175 				&&	ValidIONum(player.equiped[EQUIP_SLOT_RING_LEFT]	))
6176 			{
6177 				Entity * todraw=entities[player.equiped[EQUIP_SLOT_RING_LEFT]];
6178 
6179 				tc=todraw->inv;
6180 
6181 				if (NeedHalo(todraw)) tc2 = todraw->inv->getHalo();
6182 
6183 				if (tc)
6184 				{
6185 					todraw->bbox1.x=146;
6186 					todraw->bbox1.y=312;
6187 
6188 					Color color = (todraw->poisonous && todraw->poisonous_count != 0) ? Color::green : Color::white;
6189 					DrawBookInterfaceItem(tc, todraw->bbox1.x, todraw->bbox1.y, color, 0);
6190 
6191 					if(tc2) {
6192 						ARX_INTERFACE_HALO_Draw(
6193 							todraw, tc, tc2,
6194 							(todraw->bbox1.x + BOOKDECX) * Xratio,
6195 							(todraw->bbox1.y + BOOKDECY) * Yratio,
6196 							Xratio, Yratio
6197 						);
6198 					}
6199 
6200 					float fWidth  = todraw->bbox1.x + static_cast<float>( tc->m_dwWidth );
6201 					float fHeight = todraw->bbox1.y + static_cast<float>( tc->m_dwHeight );
6202 					todraw->bbox2.x = checked_range_cast<short>(fWidth);
6203 					todraw->bbox2.y = checked_range_cast<short>(fHeight);
6204 
6205 					float fX1 = (todraw->bbox1.x+BOOKDECX) * Xratio ;
6206 					float fX2 = (todraw->bbox2.x+BOOKDECX) * Xratio ;
6207 					float fY1 = (todraw->bbox1.y+BOOKDECY) * Yratio ;
6208 					float fY2 = (todraw->bbox2.y+BOOKDECY) * Yratio ;
6209 					todraw->bbox1.x = checked_range_cast<short>(fX1);
6210 					todraw->bbox2.x = checked_range_cast<short>(fX2);
6211 					todraw->bbox1.y = checked_range_cast<short>(fY1);
6212 					todraw->bbox2.y = checked_range_cast<short>(fY2);
6213 
6214 					todraw->ioflags |= IO_ICONIC;
6215 				}
6216 			}
6217 
6218 			tc2=NULL;
6219 
6220 			if (	(player.equiped[EQUIP_SLOT_RING_RIGHT]!=0)
6221 				&&	ValidIONum(player.equiped[EQUIP_SLOT_RING_RIGHT]	))
6222 			{
6223 				Entity * todraw=entities[player.equiped[EQUIP_SLOT_RING_RIGHT]];
6224 
6225 				tc=todraw->inv;
6226 
6227 				if (NeedHalo(todraw)) tc2=todraw->inv->getHalo();
6228 
6229 				if (tc)
6230 				{
6231 					todraw->bbox1.x=296;
6232 					todraw->bbox1.y=312;
6233 
6234 					Color color = (todraw->poisonous && todraw->poisonous_count != 0) ? Color::green : Color::white;
6235 					DrawBookInterfaceItem(tc, todraw->bbox1.x, todraw->bbox1.y, color, 0);
6236 
6237 					if(tc2) {
6238 						ARX_INTERFACE_HALO_Draw(
6239 							todraw, tc, tc2,
6240 							(todraw->bbox1.x + BOOKDECX) * Xratio,
6241 							(todraw->bbox1.y + BOOKDECX) * Yratio,
6242 							Xratio, Yratio
6243 						);
6244 					}
6245 
6246 					float fWidth  = todraw->bbox1.x + static_cast<float>( tc->m_dwWidth );
6247 					float fHeight = todraw->bbox1.y + static_cast<float>( tc->m_dwHeight );
6248 					todraw->bbox2.x = checked_range_cast<short>(fWidth);
6249 					todraw->bbox2.y = checked_range_cast<short>(fHeight);
6250 
6251 					float fX1 = (todraw->bbox1.x+BOOKDECX) * Xratio ;
6252 					float fX2 = (todraw->bbox2.x+BOOKDECX) * Xratio ;
6253 					float fY1 = (todraw->bbox1.y+BOOKDECY) * Yratio ;
6254 					float fY2 = (todraw->bbox2.y+BOOKDECY) * Yratio ;
6255 
6256 					todraw->bbox1.x = checked_range_cast<short>(fX1);
6257 					todraw->bbox2.x = checked_range_cast<short>(fX2);
6258 					todraw->bbox1.y = checked_range_cast<short>(fY1);
6259 					todraw->bbox2.y = checked_range_cast<short>(fY2);
6260 
6261 					todraw->ioflags |= IO_ICONIC;
6262 				}
6263 			}
6264 
6265 			if (!BOOKZOOM)
6266 				ARX_EQUIPMENT_AttachPlayerWeaponToBack();
6267 
6268 			//blue halo rendering (keyword : BLUE HALO RENDERING HIGHLIGHT AURA)
6269 			if (HALOCUR>0)
6270 			{
6271 				GRenderer->ResetTexture(0);
6272 				GRenderer->SetBlendFunc(Renderer::BlendSrcColor, Renderer::BlendOne);
6273 				GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6274 				GRenderer->SetCulling(Renderer::CullNone);
6275 				GRenderer->SetRenderState(Renderer::DepthWrite, false);
6276 
6277 				for (int i=0;i<HALOCUR;i++)
6278 				{
6279 					TexturedVertex * vert=&LATERDRAWHALO[(i<<2)];
6280 
6281 					if (vert[2].color == 0)
6282 					{
6283 						GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor);
6284 						vert[2].color =0xFF000000;
6285 						EERIEDRAWPRIM(Renderer::TriangleFan, vert, 4); //>>> DO NOT USE VERTEX BUFFER HERE <<<
6286 						GRenderer->SetBlendFunc(Renderer::BlendSrcColor, Renderer::BlendOne);
6287 					}
6288 					else EERIEDRAWPRIM(Renderer::TriangleFan, vert, 4); //>>> DO NOT USE VERTEX BUFFER HERE <<<
6289 				}
6290 
6291 				HALOCUR=0;
6292 				GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6293 			}
6294 		}
6295 	}
6296 }
6297 
6298 //-----------------------------------------------------------------------------
DrawAllInterfaceFinish()6299 void ArxGame::DrawAllInterfaceFinish()
6300 {
6301 	currpos = static_cast<long>(INTERFACE_RATIO(50.f));
6302 	float rrr;
6303 	rrr=1.f-PULSATE*0.5f;
6304 
6305 	if (rrr>1.f) rrr=1.f;
6306 	else if (rrr<0.f) rrr=0.f;
6307 
6308 	GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
6309 	GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6310 	PRECAST_NUM=0;
6311 
6312 	for(size_t i = 0; i < MAX_SPELLS; i++) {
6313 		if ((spells[i].exist) && (spells[i].caster==0))
6314 			if (spellicons[spells[i].type].bDuration)
6315 				ManageSpellIcon(i,rrr,0);
6316 	}
6317 
6318 	if (entities.player())
6319 	{
6320 		for (int i=0;i<entities.player()->nb_spells_on;i++)
6321 		{
6322 			if (spells[entities.player()->spells_on[i]].caster!=0)
6323 				if (spellicons[spells[i].type].bDuration)
6324 					ManageSpellIcon(entities.player()->spells_on[i],rrr,1);
6325 		}
6326 	}
6327 
6328 	if (!(player.Interface & INTER_INVENTORYALL) && !(player.Interface & INTER_MAP))
6329 	{
6330 		for(size_t i = 0; i < MAX_PRECAST; i++) {
6331 			PRECAST_NUM=i;
6332 
6333 			if (Precast[i].typ!=-1)
6334 			{
6335 				float val=rrr;
6336 
6337 				if ((Precast[i].launch_time>0) &&(float(arxtime) >= Precast[i].launch_time))
6338 				{
6339 					float tt=(float(arxtime) - Precast[i].launch_time)*( 1.0f / 1000 );
6340 
6341 					if (tt>1.f) tt=1.f;
6342 
6343 					val*=(1.f-tt);
6344 				}
6345 
6346 				ManageSpellIcon(Precast[i].typ,val,2);
6347 			}
6348 		}
6349 	}
6350 }
6351 
ARX_INTERFACE_DrawCurrentTorch()6352 void ARX_INTERFACE_DrawCurrentTorch() {
6353 
6354 	if((player.Interface & INTER_NOTE) && TSecondaryInventory != NULL
6355 	   && (openNote.type() == gui::Note::BigNote || openNote.type() == gui::Note::Book)) {
6356 		return;
6357 	}
6358 
6359 	float px = INTERFACE_RATIO(std::max(InventoryX + 110.f, 10.f));
6360 	float py = DANAESIZY - INTERFACE_RATIO(158.f + 32.f);
6361 
6362 	EERIEDrawBitmap(px, py, INTERFACE_RATIO_DWORD(CURRENT_TORCH->inv->m_dwWidth),
6363 	                INTERFACE_RATIO_DWORD(CURRENT_TORCH->inv->m_dwHeight),
6364 	                0.001f, CURRENT_TORCH->inv, Color::white);
6365 
6366 	if(rnd() <= 0.2f) {
6367 		return;
6368 	}
6369 
6370 	PARTICLE_DEF * pd = createParticle();
6371 	if(!pd) {
6372 		return;
6373 	}
6374 
6375 	pd->special = FIRE_TO_SMOKE;
6376 	pd->ov = Vec3f(px + INTERFACE_RATIO(12.f - rnd() * 3.f),
6377 	               py + INTERFACE_RATIO(rnd() * 6.f), 0.0000001f);
6378 	pd->move = Vec3f(INTERFACE_RATIO(1.5f - rnd() * 3.f),
6379 	                 -INTERFACE_RATIO(5.f + rnd() * 1.f), 0.f);
6380 	pd->scale = Vec3f(1.8f, 1.8f, 1.f);
6381 	pd->tolive = Random::get(500, 900);
6382 	pd->tc = fire2;
6383 	pd->rgb = Color3f(1.f, .6f, .5f);
6384 	pd->siz = INTERFACE_RATIO(14.f);
6385 	pd->type = PARTICLE_2D;
6386 }
6387 
6388 extern float GLOBAL_SLOWDOWN;
6389 extern long SPLASH_THINGS_STAGE;
6390 
DrawAllInterface()6391 void ArxGame::DrawAllInterface() {
6392 
6393 	GRenderer->GetTextureStage(0)->SetMinFilter(TextureStage::FilterLinear);
6394 	GRenderer->GetTextureStage(0)->SetMagFilter(TextureStage::FilterNearest);
6395 	GRenderer->GetTextureStage(0)->SetWrapMode(TextureStage::WrapClamp);
6396 
6397 	if (!EDITMODE)
6398 	{
6399 		//---------------------------------------------------------------------
6400 		if (player.Interface & INTER_COMBATMODE)
6401 		{
6402 			float j;
6403 
6404 			if (AimTime==0) j=0.2f;
6405 			else
6406 			{
6407 				if (BOW_FOCAL)
6408 				{
6409 					j=(float)(BOW_FOCAL)/710.f;
6410 				}
6411 				else
6412 				{
6413 					float at=float(arxtime)-(float)AimTime;
6414 
6415 					if (at>0.f)
6416 						bIsAiming = true;
6417 					else
6418 						bIsAiming = false;
6419 
6420 					at=at*(1.f+(1.f-GLOBAL_SLOWDOWN));
6421 					float aim = static_cast<float>(player.Full_AimTime);
6422 					j=at/aim;
6423 				}
6424 
6425 				if (j>1.f) j=1.f;
6426 				else if (j<0.2f) j=0.2f;
6427 
6428 			}
6429 
6430 			GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
6431 
6432 			GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6433 			ARX_INTERFACE_DrawItem(ITC.Get("aim_maxi"), DANAECENTERX + INTERFACE_RATIO(-320+262.f), DANAESIZY + INTERFACE_RATIO(-72.f), 0.0001f, Color::gray(j));
6434 			GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6435 			ARX_INTERFACE_DrawItem(ITC.Get("aim_empty"), DANAECENTERX + INTERFACE_RATIO(-320+262.f), DANAESIZY + INTERFACE_RATIO(-72.f), 0.0001f, Color::white);
6436 
6437 			if(bHitFlash && player.Full_Skill_Etheral_Link >= 40){
6438 				float j = 1.0f - fHitFlash;
6439 				GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
6440 				GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6441 				Color col = (j < 0.5f) ? Color3f(j*2.0f, 1, 0).to<u8>() : Color3f(1, fHitFlash, 0).to<u8>();
6442 				ARX_INTERFACE_DrawItem(ITC.Get("aim_hit"), DANAECENTERX + INTERFACE_RATIO(-320+262.f-25), DANAESIZY + INTERFACE_RATIO(-72.f-30), 0.0001f, col);
6443 				GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6444 			}
6445 		}
6446 
6447 		if (bHitFlash)
6448 		{
6449 			float fCalc = ulHitFlash + Original_framedelay ;
6450 
6451 			ulHitFlash = checked_range_cast<unsigned long>(fCalc);
6452 
6453 			if (ulHitFlash >= 500)
6454 			{
6455 				bHitFlash = false;
6456 				ulHitFlash = 0;
6457 			}
6458 		}
6459 
6460 		//---------------------------------------------------------------------
6461 		Entity * io = NULL;
6462 
6463 		if (SecondaryInventory!=NULL)
6464 		{
6465 			io = (Entity *)SecondaryInventory->io;
6466 		}
6467 		else if (player.Interface & INTER_STEAL)
6468 		{
6469 			io = ioSteal;
6470 		}
6471 
6472 		if (io!=NULL)
6473 		{
6474 			float dist = fdist(io->pos, player.pos + (Vec3f::Y_AXIS * 80.f));
6475 
6476 			if (Project.telekinesis)
6477 			{
6478 				if (dist > 900.f)
6479 				{
6480 					if (InventoryDir != -1)
6481 					{
6482 						ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
6483 
6484 						InventoryDir=-1;
6485 						SendIOScriptEvent(io,SM_INVENTORY2_CLOSE);
6486 						TSecondaryInventory=SecondaryInventory;
6487 						SecondaryInventory=NULL;
6488 					}
6489 					else
6490 					{
6491 						if (player.Interface & INTER_STEAL)
6492 						{
6493 							player.Interface &= ~INTER_STEAL;
6494 						}
6495 					}
6496 				}
6497 			}
6498 			else if (dist > 350.f)
6499 			{
6500 				if (InventoryDir != -1)
6501 				{
6502 					ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
6503 
6504 					InventoryDir=-1;
6505 					SendIOScriptEvent(io,SM_INVENTORY2_CLOSE);
6506 					TSecondaryInventory=SecondaryInventory;
6507 					SecondaryInventory=NULL;
6508 				}
6509 				else
6510 				{
6511 					if (player.Interface & INTER_STEAL)
6512 					{
6513 						player.Interface &= ~INTER_STEAL;
6514 					}
6515 				}
6516 			}
6517 		}
6518 		else if (InventoryDir != -1)
6519 		{
6520 			InventoryDir = -1;
6521 		}
6522 
6523 		if (!PLAYER_INTERFACE_HIDE_COUNT && (TSecondaryInventory != NULL))
6524 		{
6525 			ARX_INTERFACE_DrawSecondaryInventory((bool)((player.Interface & INTER_STEAL) != 0));
6526 		}
6527 
6528 		if (!PLAYER_INTERFACE_HIDE_COUNT)
6529 		{
6530 			if ((player.Interface & INTER_INVENTORY))
6531 			{
6532 
6533 				if ((player.Interface & INTER_COMBATMODE) || (player.doingmagic>=2))
6534 				{
6535 					long t = Original_framedelay * ( 1.0f / 5 ) + 2;
6536 					InventoryY += static_cast<long>(INTERFACE_RATIO_LONG(t));
6537 
6538 					if ( InventoryY > INTERFACE_RATIO( 110.f ) ) InventoryY = static_cast<long>( INTERFACE_RATIO( 110.f ) );
6539 
6540 
6541 				}
6542 				else
6543 				{
6544 					if (bInventoryClosing)
6545 					{
6546 						long t = Original_framedelay * ( 1.0f / 5 ) + 2;
6547 						InventoryY += static_cast<long>(INTERFACE_RATIO_LONG(t));
6548 
6549 						if (InventoryY > INTERFACE_RATIO(110))
6550 						{
6551 							InventoryY = static_cast<long>( INTERFACE_RATIO( 110.f ) );
6552 							bInventoryClosing = false;
6553 
6554 							player.Interface &=~ INTER_INVENTORY;
6555 
6556 							if (bInventorySwitch)
6557 							{
6558 								bInventorySwitch = false;
6559 								ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
6560 								player.Interface |= INTER_INVENTORYALL;
6561 								ARX_INTERFACE_NoteClose();
6562 								InventoryY = static_cast<long>( INTERFACE_RATIO( 121.f ) * (player.bag) );
6563 								lOldInterface=INTER_INVENTORYALL;
6564 							}
6565 						}
6566 					}
6567 					else if (InventoryY>0)
6568 					{
6569 						InventoryY -= static_cast<long>( INTERFACE_RATIO( ( Original_framedelay * ( 1.0f / 5 ) ) + 2.f ) );
6570 
6571 
6572 						if (InventoryY<0) InventoryY=0;
6573 					}
6574 				}
6575 
6576 				if (player.bag)
6577 				{
6578 					ARX_INTERFACE_DrawInventory(sActiveInventory);
6579 
6580 					arx_assert(ITC.Get("hero_inventory") != NULL);
6581 					float fCenterX	= DANAECENTERX + INTERFACE_RATIO(-320 + 35) + INTERFACE_RATIO_DWORD(ITC.Get("hero_inventory")->m_dwWidth) - INTERFACE_RATIO(32 + 3) ;
6582 					float fSizY		= DANAESIZY - INTERFACE_RATIO(101) + INTERFACE_RATIO_LONG(InventoryY) + INTERFACE_RATIO(- 3 + 25) ;
6583 
6584 					float posx = ARX_CAST_TO_INT_THEN_FLOAT( fCenterX );
6585 					float posy = ARX_CAST_TO_INT_THEN_FLOAT( fSizY );
6586 
6587 					if (sActiveInventory > 0)
6588 					{
6589 						ARX_INTERFACE_DrawItem(ITC.Get("hero_inventory_up"),	posx, posy);
6590 
6591 						if (MouseInRect(posx, posy, posx+INTERFACE_RATIO(32), posy+INTERFACE_RATIO(32)))
6592 						{
6593 							GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
6594 							GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6595 							SpecialCursor=CURSOR_INTERACTION_ON;
6596 							ARX_INTERFACE_DrawItem(ITC.Get("hero_inventory_up"), posx, posy);
6597 							GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6598 							SpecialCursor=CURSOR_INTERACTION_ON;
6599 
6600 							if (((EERIEMouseButton & 1)  && !(LastMouseClick & 1))
6601 								|| ((!(EERIEMouseButton & 1)) && (LastMouseClick & 1) && (DRAGINTER!=NULL)))
6602 							{
6603 								if (sActiveInventory > 0)
6604 								{
6605 									ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
6606 									sActiveInventory --;
6607 								}
6608 
6609 								EERIEMouseButton &=~1;
6610 							}
6611 						}
6612 					}
6613 
6614 					if (sActiveInventory < player.bag-1)
6615 					{
6616 
6617 						float fRatio = INTERFACE_RATIO(32 + 5);
6618 
6619 						posy += checked_range_cast<int>(fRatio);
6620 
6621 						ARX_INTERFACE_DrawItem(ITC.Get("hero_inventory_down"),	posx, DANAESIZY - INTERFACE_RATIO(101) + INTERFACE_RATIO_LONG(InventoryY) + INTERFACE_RATIO(-3 + 64));
6622 
6623 						if (MouseInRect(posx, posy, posx+INTERFACE_RATIO(32), posy+INTERFACE_RATIO(32)))
6624 						{
6625 							GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
6626 							GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6627 							ARX_INTERFACE_DrawItem(ITC.Get("hero_inventory_down"),	posx, DANAESIZY - INTERFACE_RATIO(101) + INTERFACE_RATIO_LONG(InventoryY) + INTERFACE_RATIO(-3 + 64));
6628 							GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6629 							SpecialCursor=CURSOR_INTERACTION_ON;
6630 
6631 							if (((EERIEMouseButton & 1)  && !(LastMouseClick & 1))
6632 								|| ((!(EERIEMouseButton & 1)) && (LastMouseClick & 1) && (DRAGINTER!=NULL)))
6633 							{
6634 								if (sActiveInventory < player.bag-1)
6635 								{
6636 									ARX_SOUND_PlayInterface(SND_BACKPACK, 0.9F + 0.2F * rnd());
6637 									sActiveInventory ++;
6638 								}
6639 
6640 								EERIEMouseButton &=~1;
6641 							}
6642 						}
6643 					}
6644 				}
6645 			}
6646 			else if ((player.Interface & INTER_INVENTORYALL) || bInventoryClosing)
6647 			{
6648 				float fSpeed = ( 1.0f / 3 );
6649 
6650 				if ((player.Interface & INTER_COMBATMODE) || (player.doingmagic>=2))
6651 				{
6652 					if (InventoryY < INTERFACE_RATIO(121)*player.bag)
6653 					{
6654 
6655 						InventoryY += static_cast<long>(INTERFACE_RATIO((Original_framedelay * fSpeed) + 2.f));
6656 					}
6657 				}
6658 				else
6659 				{
6660 					if (bInventoryClosing)
6661 					{
6662 						InventoryY += static_cast<long>(INTERFACE_RATIO((Original_framedelay * fSpeed) + 2.f));
6663 
6664 						if ( InventoryY > INTERFACE_RATIO(121) * player.bag )
6665 						{
6666 							bInventoryClosing = false;
6667 
6668 							if (player.Interface & INTER_INVENTORYALL)
6669 							{
6670 								player.Interface &=~ INTER_INVENTORYALL;
6671 							}
6672 
6673 							lOldInterface=0;
6674 						}
6675 					}
6676 					else if (InventoryY>0)
6677 					{
6678 						InventoryY -= static_cast<long>(INTERFACE_RATIO((Original_framedelay * fSpeed) + 2.f));
6679 
6680 						if (InventoryY<0)
6681 						{
6682 							InventoryY=0;
6683 						}
6684 					}
6685 				}
6686 
6687 				const float fBag		= (player.bag-1)*INTERFACE_RATIO(-121);
6688 				float fCenterX	= DANAECENTERX + INTERFACE_RATIO(-320+35);
6689 				float fSizY		= DANAESIZY - INTERFACE_RATIO(101) + INTERFACE_RATIO_LONG(InventoryY) + INTERFACE_RATIO(-3.f + 25 - 32);
6690 				const float fOffsetY	= INTERFACE_RATIO(121);
6691 
6692 				int iOffsetY = checked_range_cast<int>(fBag + fOffsetY);
6693 				int posx = checked_range_cast<int>(fCenterX);
6694 				int posy = checked_range_cast<int>(fSizY);
6695 
6696 				for (int i=0; i<player.bag; i++)
6697 				{
6698 					ARX_INTERFACE_DrawItem(ITC.Get("hero_inventory_link"), posx + INTERFACE_RATIO(45), static_cast<float>(posy + iOffsetY)) ;
6699 
6700 					ARX_INTERFACE_DrawItem(ITC.Get("hero_inventory_link"), posx+INTERFACE_RATIO_DWORD(ITC.Get("hero_inventory")->m_dwWidth)*0.5f + INTERFACE_RATIO(-16), posy+iOffsetY + INTERFACE_RATIO(-5));
6701 					ARX_INTERFACE_DrawItem(ITC.Get("hero_inventory_link"), posx+INTERFACE_RATIO_DWORD(ITC.Get("hero_inventory")->m_dwWidth) + INTERFACE_RATIO(-45-32), posy+iOffsetY + INTERFACE_RATIO(-15));
6702 
6703 					iOffsetY += checked_range_cast<int>(fOffsetY);
6704 				}
6705 
6706 				iOffsetY = checked_range_cast<int>(fBag);
6707 
6708 				for(short i = 0; i < player.bag; i++) {
6709 					ARX_INTERFACE_DrawInventory(i, 0, iOffsetY);
6710 					iOffsetY += checked_range_cast<int>(fOffsetY);
6711 				}
6712 
6713 			}
6714 		}
6715 
6716 		if (((FlyingOverIO) && !(PLAYER_MOUSELOOK_ON) && !(player.Interface & INTER_COMBATMODE)
6717 			&& (!GInput->actionPressed(CONTROLS_CUST_MAGICMODE)))
6718 			||
6719 			(((FlyingOverIO) && (config.input.autoReadyWeapon == false) && !(player.Interface & INTER_COMBATMODE)
6720 			&& (!GInput->actionPressed(CONTROLS_CUST_MAGICMODE))))
6721 			)
6722 		{
6723 			if ((FlyingOverIO->ioflags & IO_ITEM) && (!DRAGINTER))
6724 				if (SecondaryInventory!=NULL)
6725 				{
6726 					Entity * temp=(Entity *)SecondaryInventory->io;
6727 
6728 					if (temp->ioflags & IO_SHOP)
6729 					{
6730 						float px	=	DANAEMouse.x;
6731 						float py	=	static_cast<float>(DANAEMouse.y - 10);
6732 
6733 						if (InSecondaryInventoryPos(&DANAEMouse))
6734 						{
6735 							long amount=ARX_INTERACTIVE_GetPrice(FlyingOverIO,temp);
6736 							// achat
6737 							float famount	= amount - amount * ( (float)player.Full_Skill_Intuition ) * 0.005f;
6738 							// check should always be OK because amount is supposed positive
6739 							amount = checked_range_cast<long>(famount);
6740 
6741 
6742 							if ( amount <= player.gold )
6743 								ARX_INTERFACE_DrawNumber(px, py, amount, 6, Color::green);
6744 							else
6745 								ARX_INTERFACE_DrawNumber(px, py, amount, 6, Color::red);
6746 						}
6747 						else if (InPlayerInventoryPos(&DANAEMouse))
6748 						{
6749 							long amount = static_cast<long>( ARX_INTERACTIVE_GetPrice( FlyingOverIO, temp ) / 3.0f );
6750 							// achat
6751 							float famount	= amount + amount * ( (float) player.Full_Skill_Intuition ) * 0.005f;
6752 							// check should always be OK because amount is supposed positive
6753 							amount = checked_range_cast<long>( famount );
6754 
6755 
6756 							if (amount)
6757 							{
6758 								if (temp->shop_category.empty() ||
6759 									FlyingOverIO->groups.find(temp->shop_category) != FlyingOverIO->groups.end())
6760 									ARX_INTERFACE_DrawNumber(px, py, amount, 6, Color::green);
6761 								else
6762 									ARX_INTERFACE_DrawNumber(px, py, amount, 6, Color::red);
6763 							}
6764 						}
6765 					}
6766 				}
6767 
6768 				SpecialCursor=CURSOR_INTERACTION_ON;
6769 		}
6770 
6771 		ARX_INTERFACE_DrawDamagedEquipment();
6772 
6773 		if ((!(player.Interface & INTER_COMBATMODE)))
6774 		{
6775 			if (player.Interface & INTER_MINIBACK)
6776 			{
6777 				// Draw/Manage Book Icon
6778 				float px=DANAESIZX - INTERFACE_RATIO(35) + lSLID_VALUE+GL_DECAL_ICONS;
6779 				float py=DANAESIZY - INTERFACE_RATIO(148);
6780 				ARX_INTERFACE_DrawItem(ITC.Get("book"), px, py);
6781 
6782 				if (eMouseState == MOUSE_IN_BOOK_ICON)
6783 				{
6784 					GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
6785 					GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6786 					ARX_INTERFACE_DrawItem(ITC.Get("book"), px, py);
6787 					GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6788 				}
6789 
6790 				// Draw/Manage BackPack Icon
6791 				px=DANAESIZX - INTERFACE_RATIO(35) + lSLID_VALUE+GL_DECAL_ICONS;
6792 				py=DANAESIZY - INTERFACE_RATIO(113);
6793 				ARX_INTERFACE_DrawItem(ITC.Get("backpack"),px,py);
6794 
6795 				if (eMouseState == MOUSE_IN_INVENTORY_ICON)
6796 				{
6797 					GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
6798 					GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6799 					ARX_INTERFACE_DrawItem(ITC.Get("backpack"),px,py);
6800 					GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6801 				}
6802 
6803 				// Draw/Manage Steal Icon
6804 				if (player.Interface & INTER_STEAL)
6805 				{
6806 					px = static_cast<float>(-lSLID_VALUE);
6807 					py = DANAESIZY - INTERFACE_RATIO(78.f + 32);
6808 					ARX_INTERFACE_DrawItem(ITC.Get("steal"), px, py);
6809 
6810 					if (eMouseState == MOUSE_IN_STEAL_ICON)
6811 					{
6812 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
6813 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6814 						ARX_INTERFACE_DrawItem(ITC.Get("steal"), px, py);
6815 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6816 					}
6817 				}
6818 
6819 				// Draw / Manage Pick All - Close Secondary inventory icon
6820 				if (!PLAYER_INTERFACE_HIDE_COUNT && (TSecondaryInventory!=NULL))
6821 				{
6822 					px = INTERFACE_RATIO(InventoryX) + INTERFACE_RATIO(16);
6823 					py = INTERFACE_RATIO_DWORD(BasicInventorySkin->m_dwHeight) - INTERFACE_RATIO(16);
6824 					Entity * temp=(Entity *)TSecondaryInventory->io;
6825 
6826 					if (temp && !(temp->ioflags & IO_SHOP) && !(temp == ioSteal))
6827 					{
6828 						ARX_INTERFACE_DrawItem(ITC.Get("inventory_pickall"), px, py);
6829 
6830 						if (eMouseState == MOUSE_IN_INVENTORY_PICKALL_ICON)
6831 						{
6832 							GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
6833 							GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6834 							ARX_INTERFACE_DrawItem(ITC.Get("inventory_pickall"), px, py);
6835 							GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6836 						}
6837 					}
6838 
6839 					px = INTERFACE_RATIO(InventoryX) + INTERFACE_RATIO_DWORD(BasicInventorySkin->m_dwWidth) - INTERFACE_RATIO(32);
6840 
6841 					ARX_INTERFACE_DrawItem(ITC.Get("inventory_close"), px, py);
6842 
6843 					if (eMouseState == MOUSE_IN_INVENTORY_CLOSE_ICON)
6844 					{
6845 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
6846 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6847 						ARX_INTERFACE_DrawItem(ITC.Get("inventory_close"), px, py);
6848 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6849 					}
6850 				}
6851 
6852 				// Draw/Manage Advancement Icon
6853 				if ((player.Skill_Redistribute) || (player.Attribute_Redistribute))
6854 				{
6855 					px=DANAESIZX - INTERFACE_RATIO(35) + lSLID_VALUE+GL_DECAL_ICONS;
6856 					py=DANAESIZY - INTERFACE_RATIO(218);
6857 					ARX_INTERFACE_DrawItem(ITC.Get("icon_lvl_up"),px,py);
6858 
6859 					if (eMouseState == MOUSE_IN_REDIST_ICON)
6860 					{
6861 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
6862 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6863 						ARX_INTERFACE_DrawItem(ITC.Get("icon_lvl_up"),px,py);
6864 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6865 					}
6866 				}
6867 
6868 				// Draw/Manage Gold Purse Icon
6869 				if (player.gold>0)
6870 				{
6871 					px = DANAESIZX - INTERFACE_RATIO(35) + lSLID_VALUE+2+GL_DECAL_ICONS;
6872 					py = DANAESIZY - INTERFACE_RATIO(183);
6873 					ARX_INTERFACE_DrawItem(ITC.Get("gold"), px, py);
6874 
6875 					if (eMouseState == MOUSE_IN_GOLD_ICON)
6876 					{
6877 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
6878 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
6879 						SpecialCursor=CURSOR_INTERACTION_ON;
6880 						ARX_INTERFACE_DrawItem(ITC.Get("gold"), px, py);
6881 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
6882 						ARX_INTERFACE_DrawNumber(px - INTERFACE_RATIO(30), py + INTERFACE_RATIO(10 - 25), player.gold, 6, Color::white);
6883 					}
6884 				}
6885 
6886 				if (bGoldHalo)
6887 				{
6888 					float fCalc = ulGoldHaloTime + Original_framedelay;
6889 					ulGoldHaloTime = checked_range_cast<unsigned long>(fCalc);
6890 
6891 
6892 					if (ulGoldHaloTime >= 1000) //1seconde
6893 					{
6894 						bGoldHalo = false;
6895 					}
6896 
6897 					TextureContainer *tc = ITC.Get("gold");
6898 					TextureContainer *halo = tc->getHalo();
6899 
6900 					if (halo)
6901 					{
6902 						ARX_INTERFACE_HALO_Render(0.9f, 0.9f, 0.1f, HALO_ACTIVE, halo, px, py, INTERFACE_RATIO(1), INTERFACE_RATIO(1));
6903 					}
6904 				}
6905 
6906 				if (bBookHalo)
6907 				{
6908 
6909 
6910 					float fCalc = ulBookHaloTime + Original_framedelay;
6911 					ulBookHaloTime = checked_range_cast<unsigned long>(fCalc);
6912 
6913 
6914 					if (ulBookHaloTime >= 3000) //3secondes
6915 					{
6916 						bBookHalo = false;
6917 					}
6918 
6919 					float POSX = DANAESIZX-INTERFACE_RATIO(35)+lSLID_VALUE+GL_DECAL_ICONS;
6920 					float POSY = DANAESIZY-INTERFACE_RATIO(148);
6921 					TextureContainer *tc = ITC.Get("book");
6922 					TextureContainer *halo = tc->getHalo();
6923 
6924 					if (halo)
6925 					{
6926 						ARX_INTERFACE_HALO_Render(0.2f, 0.4f, 0.8f, HALO_ACTIVE, halo, POSX, POSY, INTERFACE_RATIO(1), INTERFACE_RATIO(1));
6927 					}
6928 				}
6929 			}
6930 
6931 			if (CURRENT_TORCH)
6932 				ARX_INTERFACE_DrawCurrentTorch();
6933 		}
6934 
6935 		if ((CHANGE_LEVEL_ICON>-1) && (ChangeLevel) )
6936 		{
6937 
6938 			//Setting px and py as float to avoid warning on function ARX_INTERFACE_DrawItem and MouseInRect
6939 			float px = DANAESIZX - INTERFACE_RATIO_DWORD(ChangeLevel->m_dwWidth);
6940 			float py = 0;
6941 
6942 			float vv = 0.9f - EEsin(arxtime.get_frame_time()*( 1.0f / 50 ))*0.5f+rnd()*( 1.0f / 10 );
6943 
6944 			if ( vv < 0.f ) vv = 0;
6945 			else if ( vv > 1.f ) vv = 1.f;
6946 
6947 			ARX_INTERFACE_DrawItem(ChangeLevel, px, py, 0.0001f, Color::gray(vv));
6948 
6949 			if (MouseInRect(px, py, px + INTERFACE_RATIO_DWORD(ChangeLevel->m_dwWidth), py + INTERFACE_RATIO_DWORD(ChangeLevel->m_dwHeight)))
6950 			{
6951 				SpecialCursor=CURSOR_INTERACTION_ON;
6952 
6953 				if (!(EERIEMouseButton & 1) && (LastMouseClick & 1))
6954 				{
6955 					CHANGE_LEVEL_ICON=200;
6956 				}
6957 			}
6958 		}
6959 
6960 
6961 		// Draw stealth gauge
6962 		if (SPLASH_THINGS_STAGE<11)
6963 			ARX_INTERFACE_Draw_Stealth_Gauge();
6964 
6965 		// book
6966 		if ((player.Interface & INTER_MAP )&&  (!(player.Interface & INTER_COMBATMODE)))
6967 		{
6968 			ARX_INTERFACE_ManageOpenedBook();
6969 			ARX_INTERFACE_ManageOpenedBook_Finish();
6970 		}
6971 
6972 
6973 		if (CurrSpellSymbol || player.SpellToMemorize.bSpell)
6974 		{
6975 			int count = 0;
6976 			int count2 = 0;
6977 
6978 			for (long j=0;j<6;j++)
6979 			{
6980 				if (player.SpellToMemorize.iSpellSymbols[j] != RUNE_NONE)
6981 					count++;
6982 
6983 				if (SpellSymbol[j] != RUNE_NONE)
6984 					count2 ++;
6985 			}
6986 
6987 			count = (count2>count)?count2:count;
6988 			Vec3f pos;
6989 			pos.x = DANAESIZX - ((count) * INTERFACE_RATIO(32));
6990 
6991 			if (CHANGE_LEVEL_ICON>-1) pos.x -= INTERFACE_RATIO(32);
6992 
6993 			pos.y = 0;
6994 
6995 			for (int i=0; i<6; i++)
6996 			{
6997 				bool bHalo = false;
6998 
6999 				if (SpellSymbol[i] != RUNE_NONE)
7000 				{
7001 					if (SpellSymbol[i] == player.SpellToMemorize.iSpellSymbols[i])
7002 					{
7003 						bHalo = true;
7004 					}
7005 					else
7006 					{
7007 						player.SpellToMemorize.iSpellSymbols[i] = SpellSymbol[i];
7008 
7009 						for (int j=i+1; j<6; j++)
7010 						{
7011 							player.SpellToMemorize.iSpellSymbols[j] = RUNE_NONE;
7012 						}
7013 					}
7014 				}
7015 
7016 				if (player.SpellToMemorize.iSpellSymbols[i] != RUNE_NONE)
7017 				{
7018 					EERIEDrawBitmap2(pos.x, pos.y, INTERFACE_RATIO(32), INTERFACE_RATIO(32), 0,
7019 						necklace.pTexTab[player.SpellToMemorize.iSpellSymbols[i]], Color::white);
7020 
7021 					if (bHalo)
7022 					{
7023 						TextureContainer *tc = necklace.pTexTab[player.SpellToMemorize.iSpellSymbols[i]];
7024 						TextureContainer *halo = tc->getHalo();
7025 
7026 						if (halo)
7027 						{
7028 							ARX_INTERFACE_HALO_Render(0.2f, 0.4f, 0.8f, HALO_ACTIVE, halo, pos.x, pos.y, INTERFACE_RATIO(1), INTERFACE_RATIO(1));
7029 						}
7030 					}
7031 
7032 					if (!(player.rune_flags & (RuneFlag)(1<<player.SpellToMemorize.iSpellSymbols[i])))
7033 					{
7034 						GRenderer->SetBlendFunc(Renderer::BlendInvDstColor, Renderer::BlendOne);
7035 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
7036 
7037 						EERIEDrawBitmap2(pos.x, pos.y, INTERFACE_RATIO(32), INTERFACE_RATIO(32), 0,
7038 							Movable, Color::gray(.8f));
7039 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
7040 					}
7041 
7042 					pos.x += INTERFACE_RATIO(32);
7043 				}
7044 			}
7045 
7046 			if (float(arxtime) - player.SpellToMemorize.lTimeCreation > 30000)
7047 			{
7048 				player.SpellToMemorize.bSpell = false;
7049 			}
7050 		}
7051 
7052 		if (player.Interface & INTER_LIFE_MANA)
7053 		{
7054 			TexturedVertex v[4];
7055 			float px, py;
7056 			v[0] = TexturedVertex(Vec3f(0, 0, .001f), 1.f, Color::white.toBGR(), 1, Vec2f::ZERO);
7057 			v[1] = TexturedVertex(Vec3f(0, 0, .001f), 1.f, Color::white.toBGR(), 1, Vec2f::X_AXIS);
7058 			v[2] = TexturedVertex(Vec3f(0, 0, .001f), 1.f, Color::white.toBGR(), 1, Vec2f(1.f, 1.f));
7059 			v[3] = TexturedVertex(Vec3f(0, 0, .001f), 1.f, Color::white.toBGR(), 1, Vec2f::Y_AXIS);
7060 
7061 			px = DANAESIZX - INTERFACE_RATIO(33) + INTERFACE_RATIO(1) + lSLID_VALUE;
7062 			py = DANAESIZY - INTERFACE_RATIO(81);
7063 			ARX_INTERFACE_DrawItem(ITC.Get("empty_gauge_blue"), px, py, 0.f); //399
7064 
7065 			float fnl=(float)player.life/(float)player.Full_maxlife;
7066 			float fnm=(float)player.mana/(float)player.Full_maxmana;
7067 
7068 
7069 			//---------------------------------------------------------------------
7070 			//RED GAUGE
7071 			Color ulcolor = Color::red;
7072 			float fSLID_VALUE_neg = static_cast<float>(-lSLID_VALUE);
7073 
7074 			if(player.poison > 0.f) {
7075 				float val = std::min(player.poison, 0.2f) * 255.f * 5.f;
7076 				long g = val;
7077 				ulcolor = Color(u8(255 - g), u8(g) , 0);
7078 			}
7079 
7080 			EERIEDrawBitmap2DecalY(fSLID_VALUE_neg, DANAESIZY - INTERFACE_RATIO(78),
7081 				INTERFACE_RATIO_DWORD(ITC.Get("filled_gauge_red")->m_dwWidth),
7082 				INTERFACE_RATIO_DWORD(ITC.Get("filled_gauge_red")->m_dwHeight),
7083 				0.f, ITC.Get("filled_gauge_red"), ulcolor, (1.f - fnl));
7084 
7085 			if (!(player.Interface & INTER_COMBATMODE))
7086 			{
7087 				if (MouseInRect(fSLID_VALUE_neg, DANAESIZY - INTERFACE_RATIO(78), fSLID_VALUE_neg + INTERFACE_RATIO_DWORD(ITC.Get("filled_gauge_red")->m_dwWidth), DANAESIZY - INTERFACE_RATIO(78) + INTERFACE_RATIO_DWORD(ITC.Get("filled_gauge_red")->m_dwHeight)))
7088 				{
7089 					if(	(EERIEMouseButton & 1)&&
7090 						(!(LastMouseClick & 1)) ) {
7091 							std::stringstream ss;
7092 							ss << checked_range_cast<int>(player.life);
7093 							ARX_SPEECH_Add(ss.str());
7094 					}
7095 				}
7096 			}
7097 
7098 			//---------------------------------------------------------------------
7099 			//END RED GAUGE
7100 
7101 			px = 0.f-lSLID_VALUE;
7102 			py = DANAESIZY - INTERFACE_RATIO(78);
7103 			ARX_INTERFACE_DrawItem(ITC.Get("empty_gauge_red"), px, py, 0.001f);
7104 
7105 			//---------------------------------------------------------------------
7106 			//BLUE GAUGE
7107 
7108 			float LARGG=INTERFACE_RATIO_DWORD(ITC.Get("filled_gauge_blue")->m_dwWidth);
7109 			float HAUTT=INTERFACE_RATIO_DWORD(ITC.Get("filled_gauge_blue")->m_dwHeight);
7110 
7111 			EERIEDrawBitmap2DecalY(DANAESIZX - INTERFACE_RATIO(33) + INTERFACE_RATIO(1) + lSLID_VALUE,
7112 				DANAESIZY - INTERFACE_RATIO(81), LARGG, HAUTT, 0.f,
7113 				ITC.Get("filled_gauge_blue"), Color::white, (1.f - fnm));
7114 
7115 			if (!(player.Interface & INTER_COMBATMODE))
7116 			{
7117 				if(MouseInRect(DANAESIZX - INTERFACE_RATIO(33) + lSLID_VALUE,DANAESIZY - INTERFACE_RATIO(81),DANAESIZX - INTERFACE_RATIO(33) + lSLID_VALUE+LARGG,DANAESIZY - INTERFACE_RATIO(81)+HAUTT))
7118 				{
7119 					if(	(EERIEMouseButton & 1)&&
7120 						(!(LastMouseClick & 1)) ) {
7121 							std::stringstream ss;
7122 							ss << checked_range_cast<int>(player.mana);
7123 							ARX_SPEECH_Add(ss.str());
7124 					}
7125 				}
7126 			}
7127 
7128 			//---------------------------------------------------------------------
7129 			//END BLUE GAUGE
7130 			if (bRenderInCursorMode)
7131 			{
7132 				GRenderer->SetRenderState(Renderer::AlphaBlending, true);
7133 				GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
7134 
7135 				if (mecanism_tc && (MAGICMODE < 0) && (lNbToDrawMecanismCursor < 3))
7136 				{
7137 					Color lcolorMecanism = Color::white;
7138 					if(lTimeToDrawMecanismCursor > 300) {
7139 						lcolorMecanism = Color::black;
7140 						if(lTimeToDrawMecanismCursor > 400) {
7141 							lTimeToDrawMecanismCursor=0;
7142 							lNbToDrawMecanismCursor++;
7143 						}
7144 					}
7145 
7146 					lTimeToDrawMecanismCursor += static_cast<long>(FrameDiff);
7147 					EERIEDrawBitmap(0, 0, INTERFACE_RATIO_DWORD(mecanism_tc->m_dwWidth), INTERFACE_RATIO_DWORD(mecanism_tc->m_dwHeight), 0.01f, mecanism_tc, lcolorMecanism);
7148 				}
7149 
7150 				if (arrow_left_tc)
7151 				{
7152 					float fSizeX=INTERFACE_RATIO_DWORD(arrow_left_tc->m_dwWidth);
7153 					float fSizeY=INTERFACE_RATIO_DWORD(arrow_left_tc->m_dwHeight);
7154 					Color lcolor = Color::gray(.5f);
7155 					static float fArrowMove=0.f;
7156 					fArrowMove+=.5f*FrameDiff;
7157 
7158 					if (fArrowMove > 180.f)
7159 						fArrowMove=0.f;
7160 
7161 					float fMove=fabs(sin(radians(fArrowMove)))*fSizeX*.5f;
7162 
7163 					// Left
7164 					EERIEDrawBitmap(0 + fMove, DANAECENTERY - (fSizeY * .5f), fSizeX, fSizeY, 0.01f,
7165 						arrow_left_tc, lcolor);
7166 
7167 					// Right
7168 					EERIEDrawBitmapUVs(DANAESIZX - fSizeX - fMove, DANAECENTERY - (fSizeY * .5f), fSizeX, fSizeY,
7169 						.01f, arrow_left_tc, lcolor, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f);
7170 
7171 					// Up
7172 					EERIEDrawBitmapUVs(DANAECENTERX - (fSizeY * .5f), 0.f + fMove, fSizeY, fSizeX, .01f,
7173 						arrow_left_tc, lcolor, 0.f, 1.f, 0.f, 0.f, 1.f, 1.f, 1.f, 0.f);
7174 
7175 					// Down
7176 					EERIEDrawBitmapUVs(DANAECENTERX - (fSizeY * .5f), (DANAESIZY - fSizeX) - fMove, fSizeY, fSizeX,
7177 						.01f, arrow_left_tc, lcolor, 1.f, 1.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f);
7178 				}
7179 
7180 				GRenderer->SetRenderState(Renderer::AlphaBlending, false);
7181 			}
7182 		}
7183 	}
7184 
7185 	GRenderer->GetTextureStage(0)->SetMinFilter(TextureStage::FilterLinear);
7186 	GRenderer->GetTextureStage(0)->SetMagFilter(TextureStage::FilterLinear);
7187 	GRenderer->GetTextureStage(0)->SetWrapMode(TextureStage::WrapRepeat);
7188 }
7189 
7190 extern long FRAME_COUNT;
7191 extern Entity * DESTROYED_DURING_RENDERING;
7192 extern float STARTED_ANGLE;
7193 long SPECIAL_DRAGINTER_RENDER=0;
7194 long CANNOT_PUT_IT_HERE=0;
7195 
Manage3DCursor(long flags)7196 long Manage3DCursor(long flags)
7197 {
7198 	if (BLOCK_PLAYER_CONTROLS)
7199 		return 0;
7200 
7201 	float ag=player.angle.a;
7202 
7203 	if (ag>180) ag=ag-360;
7204 
7205 	float drop_miny=(float)(DANAECENTERY)-DANAECENTERY*(ag*( 1.0f / 70 ));
7206 
7207 	if ((DANAEMouse.y<drop_miny) && (!EDITMODE))
7208 		return 0;
7209 
7210 	Entity * io=DRAGINTER;
7211 
7212 	if (!io) return 0;
7213 
7214 	Anglef temp;
7215 
7216 	if (io->ioflags & IO_INVERTED)
7217 	{
7218 		temp.a=180.f;
7219 		temp.b = -MAKEANGLE(270.f - io->angle.b - (player.angle.b - STARTED_ANGLE));
7220 	}
7221 	else
7222 	{
7223 		temp.a = 0;
7224 		temp.b = MAKEANGLE(270.f - io->angle.b - (player.angle.b - STARTED_ANGLE));
7225 	}
7226 
7227 	temp.g = 0;
7228 	Vec3f pos;
7229 	float angle=radians(MAKEANGLE(player.angle.b));
7230 	float angle2=radians(MAKEANGLE(player.angle.b-90.f));
7231 
7232 	float zrange=(DANAESIZY-DANAEMouse.y)/(DANAESIZY-drop_miny); //between 0 (bottom) and 1 (top)
7233 	float va=player.angle.a;
7234 
7235 	if (va>180) va=0;
7236 
7237 				float vd=(100.f-va)*( 1.0f / 90 );
7238 				float mod=va-50.f;
7239 
7240 				if (mod<0) mod=0;
7241 
7242 				mod*=( 1.0f / 20 );
7243 	va = (vd) * (1.3f + 0.3f * mod);
7244 
7245 				vd=((1.f-zrange)*0.6f-vd)*150.f;
7246 
7247 				if (va<0) va=0;
7248 
7249 				if (vd<0) vd=0;
7250 
7251 				float mx = DANAEMouse.x;
7252 
7253 				if (TRUE_PLAYER_MOUSELOOK_ON && (config.input.autoReadyWeapon))
7254 				{
7255 					mx = MemoMouse.x;
7256 				}
7257 
7258 				pos.x=player.pos.x+EEsin(angle2)*(DANAECENTERX-mx)*0.7f*va
7259 					-EEsin(angle)*(va*zrange*400.f+vd);
7260 
7261 				pos.z=player.pos.z-EEcos(angle2)*(DANAECENTERX-mx)*0.7f*va
7262 					+EEcos(angle)*(va*zrange*400.f+vd);
7263 
7264 				pos.y=player.pos.y;
7265 
7266 				{
7267 					Vec3f objcenter = Vec3f::ZERO;
7268 					float maxdist= 0.f;
7269 					float miny=  99999999.f;
7270 					float maxy= -99999999.f;
7271 					Vec3f minoff;
7272 					Vec3f maxoff;
7273 					maxoff = minoff = io->obj->vertexlist[0].v;
7274 					for(size_t i = 0; i < io->obj->vertexlist.size(); i++) {
7275 						maxoff = componentwise_max(maxoff, io->obj->vertexlist[i].v);
7276 						minoff = componentwise_min(minoff, io->obj->vertexlist[i].v);
7277 						miny = std::min(miny, io->obj->vertexlist[i].v.y);
7278 						maxy = std::max(maxy, io->obj->vertexlist[i].v.y);
7279 					}
7280 
7281 					EERIE_CYLINDER cyl;
7282 					cyl.origin.x=pos.x-(maxoff.x-minoff.x)*0.5f;
7283 					cyl.origin.y=pos.y;
7284 					cyl.origin.z=pos.z-(maxoff.z-minoff.z)*0.5f;
7285 					cyl.height=-50.f;
7286 					cyl.radius=40.f;
7287 
7288 					Vec3f orgn,dest,mvectx;
7289 		mvectx.x = -(float)EEsin(radians(player.angle.b - 90.f));
7290 		mvectx.y = 0;
7291 		mvectx.z = +(float)EEcos(radians(player.angle.b - 90.f));
7292 					mvectx.normalize();
7293 
7294 					float xmod=(float)(DANAEMouse.x-DANAECENTERX)/(float)DANAECENTERX*160.f;
7295 					float ymod=(float)(DANAEMouse.y-DANAECENTERY)/(float)DANAECENTERY*220.f;
7296 					mvectx *= xmod;
7297 					Vec3f mvecty(0, ymod, 0);
7298 
7299 					orgn.x=player.pos.x-(float)EEsin(radians(player.angle.b))*(float)EEcos(radians(player.angle.a))*50.f
7300 		         + mvectx.x;
7301 					orgn.y=player.pos.y+(float)EEsin(radians(player.angle.a))*50.f
7302 							+mvectx.y+mvecty.y;
7303 					orgn.z=player.pos.z+(float)EEcos(radians(player.angle.b))*(float)EEcos(radians(player.angle.a))*50.f
7304 		         + mvectx.z;
7305 
7306 					dest.x=player.pos.x-(float)EEsin(radians(player.angle.b))*(float)EEcos(radians(player.angle.a))*10000.f
7307 		         + mvectx.x;
7308 					dest.y=player.pos.y+(float)EEsin(radians(player.angle.a))*10000.f
7309 							+mvectx.y+mvecty.y*5.f;
7310 					dest.z=player.pos.z+(float)EEcos(radians(player.angle.b))*(float)EEcos(radians(player.angle.a))*10000.f
7311 		         + mvectx.z;
7312 					pos = orgn;
7313 
7314 					Vec3f movev = (dest - orgn).getNormalized();
7315 
7316 					float lastanything = 0.f;
7317 					float height = -( maxy - miny );
7318 
7319 					if ( height > -30.f ) height = -30.f;
7320 
7321 		objcenter.x	=	minoff.x + (maxoff.x - minoff.x) * 0.5f;
7322 		objcenter.y	=	0;
7323 		objcenter.z	=	minoff.z + (maxoff.z - minoff.z) * 0.5f;
7324 
7325 					for ( size_t i = 0 ; i < io->obj->vertexlist.size() ; i++ )
7326 					{
7327 						maxdist = std::max(maxdist, dist(Vec2f(objcenter.x, objcenter.z),
7328 			                               Vec2f(io->obj->vertexlist[i].v.x, io->obj->vertexlist[i].v.z)) - 4.f);
7329 					}
7330 
7331 					if (io->obj->pbox)
7332 					{
7333 						for (int i=1;i<io->obj->pbox->nb_physvert;i++)
7334 						{
7335 							maxdist = std::max(maxdist, dist(Vec2f(io->obj->pbox->vert[0].initpos.x,
7336 												io->obj->pbox->vert[0].initpos.z),
7337 												Vec2f(io->obj->pbox->vert[i].initpos.x,
7338 				                               io->obj->pbox->vert[i].initpos.z)) + 14.f);
7339 						}
7340 					}
7341 
7342 					VRotateY(&objcenter,temp.b);
7343 
7344 					if ( maxdist < 15.f ) maxdist = 15.f;
7345 
7346 					if ( maxdist > 150.f ) maxdist = 150.f;
7347 
7348 		bool			bCollidposNoInit = true;
7349 					Vec3f		collidpos = Vec3f::ZERO;
7350 					EERIE_CYLINDER	cyl2;
7351 					float			inc			=	10.f;
7352 					long			iterating	=	40;
7353 
7354 		cyl2.height = std::min(-30.f, height);
7355 		cyl2.radius = std::max(20.f, maxdist);
7356 
7357 
7358 					while ( iterating>0 )
7359 					{
7360 
7361 			cyl2.origin.x = pos.x + movev.x * inc;
7362 			cyl2.origin.y = pos.y + movev.y * inc + maxy;
7363 			cyl2.origin.z = pos.z + movev.z * inc;
7364 
7365 						float anything = CheckAnythingInCylinder( &cyl2, io, CFLAG_JUST_TEST | CFLAG_COLLIDE_NOCOL | CFLAG_NO_NPC_COLLIDE );
7366 
7367 						if ( anything < 0.f )
7368 						{
7369 							if ( iterating == 40 )
7370 							{
7371 								CANNOT_PUT_IT_HERE = 1;
7372 								return -1;
7373 							}
7374 
7375 							iterating = 0;
7376 
7377 							collidpos = cyl2.origin;
7378 				bCollidposNoInit = false;
7379 
7380 							if(lastanything < 0.f) {
7381 								pos.y += lastanything;
7382 								collidpos.y += lastanything;
7383 							}
7384 						} else {
7385 							pos = cyl2.origin;
7386 							lastanything = anything;
7387 						}
7388 
7389 						iterating--;
7390 					}
7391 
7392 					collidpos.x	-=	objcenter.x;
7393 					collidpos.z	-=	objcenter.z;
7394 					pos.x		-=	objcenter.x;
7395 					pos.z		-=	objcenter.z;
7396 
7397 					if ( iterating != -1 )
7398 					{
7399 						CANNOT_PUT_IT_HERE = 1;
7400 						return 0;
7401 					}
7402 
7403 		if ((iterating == -1) && closerThan(player.pos, pos, 300.f))
7404 					{
7405 						if ( flags & 1 )
7406 						{
7407 							io->obj->drawflags |= DRAWFLAG_HIGHLIGHT;
7408 							ARX_INTERACTIVE_Teleport( io, &pos, 1 );
7409 
7410 							int iOldFrameCount	=	FRAME_COUNT;
7411 							FRAME_COUNT			=	0;
7412 							io->gameFlags		&=	~GFLAG_NOCOMPUTATION;
7413 
7414 							float old			=	io->invisibility;
7415 
7416 
7417 							if( bCollidposNoInit )
7418 							{
7419 					ARX_DEAD_CODE();
7420 							}
7421 
7422 							if (SPECIAL_DRAGINTER_RENDER)
7423 							{
7424 
7425 							if (((lastanything<0.f) && (EEfabs(lastanything)>EEfabs(height)))
7426 								|| (lastanything>EEfabs(height)))
7427 							{
7428 						io->invisibility = 0.5f;
7429 								DrawEERIEInter(io->obj,&temp,&collidpos,io);
7430 								io->invisibility=old;
7431 							}
7432 							else if (lastanything>0.f)
7433 						DrawEERIEInter( io->obj, &temp, &pos, io);
7434 							else
7435 								DrawEERIEInter(io->obj,&temp,&pos,io);
7436 							}
7437 
7438 							PrecalcIOLighting(NULL,0,1);
7439 							FRAME_COUNT=iOldFrameCount;
7440 
7441 							if (!SPECIAL_DRAGINTER_RENDER && !DESTROYED_DURING_RENDERING)
7442 							{
7443 								io->obj->drawflags&=~DRAWFLAG_HIGHLIGHT;
7444 
7445 								if (io->ignition>0.f)
7446 									ManageIgnition(io);
7447 							}
7448 						}
7449 						else
7450 						{
7451 				if (EEfabs(lastanything) > std::min(EEfabs(height), 12.0f))
7452 							{
7453 								Entity * io=DRAGINTER;
7454 								ARX_PLAYER_Remove_Invisibility();
7455 								io->obj->pbox->active=1;
7456 								io->obj->pbox->stopcount=0;
7457 								Vec3f pos = io->pos = collidpos;
7458 								io->velocity = Vec3f::ZERO;
7459 
7460 								io->stopped = 1;
7461 
7462 								movev.x *= 0.0001f;
7463 								movev.y = 0.1f;
7464 								movev.z *= 0.0001f;
7465 								Vec3f viewvector = movev;
7466 
7467 								Anglef angle = temp;
7468 								io->soundtime=0;
7469 								io->soundcount=0;
7470 								EERIE_PHYSICS_BOX_Launch(io->obj,&pos,&viewvector,1,&angle);
7471 								ARX_SOUND_PlaySFX(SND_WHOOSH, &pos);
7472 								io->show=SHOW_FLAG_IN_SCENE;
7473 								Set_DragInter(NULL);
7474 							}
7475 							else
7476 							{
7477 
7478 								ARX_PLAYER_Remove_Invisibility();
7479 								ARX_SOUND_PlayInterface(SND_INVSTD);
7480 								ARX_INTERACTIVE_Teleport(io,&pos,1);
7481 
7482 								io->angle.a=temp.a;
7483 								io->angle.b=270.f-temp.b;
7484 								io->angle.g=temp.g;
7485 								io->stopped=0;
7486 								io->show=SHOW_FLAG_IN_SCENE;
7487 								io->obj->pbox->active=0;
7488 								Set_DragInter(NULL);
7489 							}
7490 						}
7491 
7492 						GRenderer->SetCulling(Renderer::CullNone);
7493 						return 1;
7494 					}
7495 					else
7496 					{
7497 						CANNOT_PUT_IT_HERE=-1;
7498 					}
7499 				}
7500 
7501 				return 0;
7502 
7503 }
7504 //-----------------------------------------------------------------------------
ARX_INTERFACE_RenderCursorInternal(long flag)7505 void ARX_INTERFACE_RenderCursorInternal(long flag)
7506 {
7507 	if (!SPECIAL_DRAGINTER_RENDER)
7508 	{
7509 		ManageIgnition_2(DRAGINTER);
7510 		GRenderer->GetTextureStage(0)->SetMinFilter(TextureStage::FilterNearest);
7511 		GRenderer->GetTextureStage(0)->SetMagFilter(TextureStage::FilterNearest);
7512 		GRenderer->GetTextureStage(0)->SetWrapMode(TextureStage::WrapClamp);
7513 	}
7514 
7515 	TextureContainer * surf;
7516 
7517 	if (!SPECIAL_DRAGINTER_RENDER)
7518 	{
7519 		if (LOOKING_FOR_SPELL_TARGET)
7520 		{
7521 			if (float(arxtime) > LOOKING_FOR_SPELL_TARGET_TIME+7000)
7522 			{
7523 				ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE, &player.pos);
7524 				ARX_SPELLS_CancelSpellTarget();
7525 			}
7526 
7527 			if (	(FlyingOverIO)
7528 				&&	(	((LOOKING_FOR_SPELL_TARGET & 1) && (FlyingOverIO->ioflags & IO_NPC))
7529 				|| ((LOOKING_FOR_SPELL_TARGET & 2) && (FlyingOverIO->ioflags & IO_ITEM))	)	)
7530 			{
7531 				surf=ITC.Get("target_on");
7532 
7533 				if (!(EERIEMouseButton & 1) && (LastMouseClick & 1))
7534 				{
7535 					ARX_SPELLS_LaunchSpellTarget(FlyingOverIO);
7536 				}
7537 			}
7538 			else
7539 			{
7540 				surf=ITC.Get("target_off");
7541 
7542 				if(GInput->actionPressed(CONTROLS_CUST_MAGICMODE))
7543 				{
7544 					ARX_SOUND_PlaySFX(SND_MAGIC_FIZZLE, &player.pos);
7545 					ARX_SPELLS_CancelSpellTarget();
7546 				}
7547 			}
7548 
7549 			float POSX=DANAEMouse.x;
7550 			float POSY=DANAEMouse.y;
7551 
7552 			if (TRUE_PLAYER_MOUSELOOK_ON)
7553 			{
7554 				POSX = MemoMouse.x;
7555 				POSY = MemoMouse.y;
7556 			}
7557 
7558 
7559 			float fTexSizeX = INTERFACE_RATIO_DWORD(surf->m_dwWidth);
7560 			float fTexSizeY = INTERFACE_RATIO_DWORD(surf->m_dwHeight);
7561 
7562 			EERIEDrawBitmap((float)(POSX-(fTexSizeX*0.5f)), (float)(POSY-(surf->m_dwHeight*0.5f)), fTexSizeX, fTexSizeY, 0.f, surf, Color::white);
7563 
7564 			return;
7565 		}
7566 	}
7567 
7568 	if (flag || ((!BLOCK_PLAYER_CONTROLS) &&
7569 		(!PLAYER_INTERFACE_HIDE_COUNT)))
7570 	{
7571 
7572 		if (!SPECIAL_DRAGINTER_RENDER)
7573 			GRenderer->SetCulling(Renderer::CullNone);
7574 
7575 		if ((COMBINE) || (COMBINEGOLD))
7576 		{
7577 			if (SpecialCursor==CURSOR_INTERACTION_ON)
7578 				SpecialCursor=CURSOR_COMBINEON;
7579 			else SpecialCursor=CURSOR_COMBINEOFF;
7580 		}
7581 
7582 		if ((SpecialCursor) || !PLAYER_MOUSELOOK_ON || (DRAGINTER!=NULL)
7583 		        || ((FlyingOverIO) && PLAYER_MOUSELOOK_ON && !(ARX_MOUSE_OVER & ARX_MOUSE_OVER_BOOK)
7584 			&& (eMouseState != MOUSE_IN_NOTE)
7585 			&& (FlyingOverIO->ioflags & IO_ITEM)
7586 			&& (FlyingOverIO->gameFlags & GFLAG_INTERACTIVITY)
7587 			&& (config.input.autoReadyWeapon == false))
7588 			|| ((MAGICMODE==1) && PLAYER_MOUSELOOK_ON))
7589 		{
7590 
7591 			if (!SPECIAL_DRAGINTER_RENDER)
7592 			{
7593 				if(FlyingOverIO||DRAGINTER)
7594 				{
7595 					fHighLightAng+=(float)(FrameDiff*0.5);
7596 
7597 					if(fHighLightAng>90.f) fHighLightAng=90.f;
7598 
7599 
7600 					float fHLight	= 100.f*sin(radians(fHighLightAng));
7601 
7602 					iHighLight = checked_range_cast<int>(fHLight);
7603 
7604 
7605 				}
7606 				else
7607 				{
7608 					 fHighLightAng=0.f;
7609 					iHighLight = 0;
7610 				}
7611 			}
7612 
7613 
7614 			CANNOT_PUT_IT_HERE=0;
7615 			float ag=player.angle.a;
7616 
7617 			if (ag>180) ag=ag-360;
7618 
7619 			float drop_miny=(float)(DANAECENTERY)-DANAECENTERY*(ag*( 1.0f / 70 ));
7620 
7621 			if ((DANAEMouse.y>drop_miny) && DRAGINTER && !InInventoryPos(&DANAEMouse)
7622 			        && !(ARX_MOUSE_OVER & ARX_MOUSE_OVER_BOOK))
7623 			{
7624 				if (Manage3DCursor(1)==0)
7625 					CANNOT_PUT_IT_HERE = -1;
7626 
7627 				if (SPECIAL_DRAGINTER_RENDER)
7628 				{
7629 
7630 					CANNOT_PUT_IT_HERE=0;
7631 					return;
7632 				}
7633 
7634 			}
7635 			else CANNOT_PUT_IT_HERE = -1;
7636 
7637 			if (SPECIAL_DRAGINTER_RENDER)
7638 				return;
7639 
7640 			float POSX,POSY;
7641 
7642 			POSX=(float)DANAEMouse.x;
7643 			POSY=(float)DANAEMouse.y;
7644 
7645 
7646 			if ((SpecialCursor) && (!DRAGINTER))
7647 			{
7648 				if (((COMBINE!=NULL) && (COMBINE->inv!=NULL)) || COMBINEGOLD)
7649 				{
7650 					if (TRUE_PLAYER_MOUSELOOK_ON && (config.input.autoReadyWeapon))
7651 					{
7652 						POSX = MemoMouse.x;
7653 						POSY = MemoMouse.y;
7654 					}
7655 
7656 					TextureContainer * tc;
7657 
7658 					if (COMBINEGOLD) tc=GoldCoinsTC[5];
7659 					else tc=COMBINE->inv;
7660 
7661 					float MODIF=0.f;
7662 
7663 
7664 					float fTexSizeX = INTERFACE_RATIO_DWORD(tc->m_dwWidth);
7665 					float fTexSizeY = INTERFACE_RATIO_DWORD(tc->m_dwHeight);
7666 
7667 
7668 					if (SpecialCursor==CURSOR_COMBINEON)
7669 					{
7670 						EERIEDrawBitmap(POSX + MODIF, POSY + MODIF, fTexSizeX, fTexSizeY, .00001f, tc, Color::white);
7671 
7672 						if ((FlyingOverIO!=NULL) && (FlyingOverIO->ioflags & IO_BLACKSMITH))
7673 						{
7674 							float v=ARX_DAMAGES_ComputeRepairPrice(COMBINE,FlyingOverIO);
7675 
7676 							if (v>0.f)
7677 							{
7678 								long t = v;
7679 								ARX_INTERFACE_DrawNumber(POSX + MODIF - 16, POSY + MODIF - 10, t, 6, Color::cyan);
7680 							}
7681 						}
7682 					}
7683 					else
7684 						EERIEDrawBitmap(POSX + MODIF, POSY + MODIF, fTexSizeX, fTexSizeY, 0.00001f, tc, Color::fromBGRA(0xFFFFAA66));
7685 				}
7686 
7687 				switch (SpecialCursor)
7688 				{
7689 				case CURSOR_REDIST:
7690 					{
7691 						surf = ITC.Get("ptexcursorredist");
7692 					}
7693 					break;
7694 				case CURSOR_COMBINEOFF:
7695 					surf=ITC.Get("target_off");
7696 						POSX -= 16.f;
7697 						POSY -= 16.f;
7698 					break;
7699 				case CURSOR_COMBINEON:
7700 					surf=ITC.Get("target_on");
7701 
7702 					if (surf)
7703 							POSX -= 16.f;
7704 
7705 						POSY -= 16.f;
7706 					break;
7707 				case CURSOR_FIREBALLAIM: {
7708 					surf=ITC.Get("target_on");
7709 
7710 					Vec2i size;
7711 					if(surf) {
7712 						size = Vec2i(surf->m_dwWidth, surf->m_dwHeight);
7713 					} else {
7714 						ARX_DEAD_CODE();
7715 						size = Vec2i::ZERO;
7716 					}
7717 
7718 					POSX = 320.f - size.x / 2.f;
7719 					POSY = 280.f - size.y / 2.f;
7720 					break;
7721 				}
7722 				case CURSOR_INTERACTION_ON:
7723 
7724 					CURCURTIME += checked_range_cast<long>(Original_framedelay);
7725 
7726 
7727 					if (CURCURPOS!=3)
7728 					{
7729 						while(CURCURTIME>CURCURDELAY)
7730 						{
7731 							CURCURTIME-=CURCURDELAY;
7732 							CURCURPOS++;
7733 						}
7734 					}
7735 
7736 					if (CURCURPOS>7) CURCURPOS=0;
7737 
7738 					surf=scursor[CURCURPOS];
7739 					break;
7740 				default:
7741 					if (CURCURPOS!=0)
7742 					{
7743 
7744 						CURCURTIME += checked_range_cast<long>(Original_framedelay);
7745 
7746 						while(CURCURTIME>CURCURDELAY)
7747 						{
7748 							CURCURTIME-=CURCURDELAY;
7749 							CURCURPOS++;
7750 						}
7751 					}
7752 
7753 					if (CURCURPOS>7) CURCURPOS=0;
7754 
7755 					surf=scursor[CURCURPOS];
7756 					break;
7757 				}
7758 
7759 				if (surf)
7760 				{
7761 
7762 					if (SpecialCursor == CURSOR_REDIST)
7763 					{
7764 						EERIEDrawBitmap(POSX, POSY, surf->m_dwWidth * Xratio, surf->m_dwHeight * Yratio,
7765 						                0.f, surf, Color::white);
7766 
7767 						std::stringstream ss;
7768 						ss << std::setw(3) << lCursorRedistValue;
7769 						ARX_TEXT_Draw(hFontInBook, DANAEMouse.x + 6* Xratio, DANAEMouse.y + 11* Yratio, ss.str(), Color::black);
7770 					}
7771 					else
7772 					{
7773 
7774 						float fTexSizeX = INTERFACE_RATIO_DWORD(surf->m_dwWidth);
7775 						float fTexSizeY = INTERFACE_RATIO_DWORD(surf->m_dwHeight);
7776 
7777 						EERIEDrawBitmap(POSX, POSY, fTexSizeX, fTexSizeY, 0.f, surf, Color::white);
7778 					}
7779 				}
7780 
7781 				SpecialCursor=0;
7782 			}
7783 			else
7784 			{
7785 				if (!(player.Current_Movement & PLAYER_CROUCH) && (!BLOCK_PLAYER_CONTROLS
7786 					&& (GInput->actionPressed(CONTROLS_CUST_MAGICMODE)))
7787 					&& (ARXmenu.currentmode==AMCM_OFF))
7788 				{
7789 					if (MAGICMODE<0)
7790 					{
7791 						if (player.Interface & INTER_MAP )
7792 						{
7793 							ARX_INTERFACE_BookOpenClose(2); // Forced Closing
7794 						}
7795 
7796 						MAGICMODE=1;
7797 					}
7798 
7799 					surf=ITC.Get("magic");
7800 
7801 					float POSX=DANAEMouse.x;
7802 					float POSY=DANAEMouse.y;
7803 
7804 					if (TRUE_PLAYER_MOUSELOOK_ON)
7805 					{
7806 						POSX = MemoMouse.x;
7807 						POSY = MemoMouse.y;
7808 					}
7809 
7810 
7811 					float fTexSizeX = INTERFACE_RATIO_DWORD(surf->m_dwWidth);
7812 					float fTexSizeY = INTERFACE_RATIO_DWORD(surf->m_dwHeight);
7813 
7814 
7815 					EERIEDrawBitmap(POSX - (fTexSizeX*0.5f), POSY - (fTexSizeY*0.5f), fTexSizeX, fTexSizeY,
7816 					                0.f, surf, Color::white);
7817 				}
7818 				else
7819 				{
7820 					if (MAGICMODE>-1)
7821 					{
7822 						ARX_SOUND_Stop(SND_MAGIC_DRAW);
7823 						MAGICMODE=-1;
7824 					}
7825 
7826 					if ((DRAGINTER!=NULL) && (DRAGINTER->inv!=NULL))
7827 					{
7828 						TextureContainer * tc;
7829 						TextureContainer * tc2=NULL;
7830 						tc=DRAGINTER->inv;
7831 
7832 						if (NeedHalo(DRAGINTER)) tc2=DRAGINTER->inv->getHalo();//>_itemdata->halo_tc;
7833 
7834 						Color color = (DRAGINTER->poisonous && DRAGINTER->poisonous_count != 0) ? Color::green : Color::white;
7835 
7836 						float mx = POSX;
7837 						float my = POSY;
7838 
7839 						if (TRUE_PLAYER_MOUSELOOK_ON && (config.input.autoReadyWeapon))
7840 						{
7841 							mx = MemoMouse.x;
7842 							my = MemoMouse.y;
7843 						}
7844 
7845 						float fTexSizeX = INTERFACE_RATIO_DWORD(tc->m_dwWidth);
7846 						float fTexSizeY = INTERFACE_RATIO_DWORD(tc->m_dwHeight);
7847 
7848 
7849 						if (!(DRAGINTER->ioflags & IO_MOVABLE))
7850 						{
7851 							EERIEDrawBitmap(mx, my, fTexSizeX, fTexSizeY, .00001f, tc, color);
7852 
7853 							if ((DRAGINTER->ioflags & IO_ITEM) && (DRAGINTER->_itemdata->count!=1))
7854 								ARX_INTERFACE_DrawNumber(mx + 2.f, my + 13.f, DRAGINTER->_itemdata->count, 3, Color::white);
7855 						}
7856 						else
7857 						{
7858 							if ((InInventoryPos(&DANAEMouse) || InSecondaryInventoryPos(&DANAEMouse))
7859 								|| (CANNOT_PUT_IT_HERE != -1)) {
7860 								EERIEDrawBitmap(mx, my, fTexSizeX, fTexSizeY, .00001f, tc, color);
7861 							}
7862 						}
7863 
7864 						//cross not over inventory icon
7865 						if ((CANNOT_PUT_IT_HERE!=0) && (eMouseState != MOUSE_IN_INVENTORY_ICON))
7866 						{
7867 							if (!InInventoryPos(&DANAEMouse) && !InSecondaryInventoryPos(&DANAEMouse) && !ARX_INTERFACE_MouseInBook())
7868 							{
7869 								TextureContainer * tcc=Movable;
7870 
7871 								if (CANNOT_PUT_IT_HERE==-1)
7872 									tcc=ThrowObject;
7873 
7874 								if ((tcc) && (tcc!=tc)) // to avoid movable double red cross...
7875 									EERIEDrawBitmap(mx + 16, my, INTERFACE_RATIO_DWORD(tcc->m_dwWidth),
7876 									                INTERFACE_RATIO_DWORD(tcc->m_dwHeight), 0.00001f, tcc, Color::white);
7877 							}
7878 						}
7879 
7880 						if (tc2)
7881 						{
7882 							ARX_INTERFACE_HALO_Draw(DRAGINTER,tc,tc2,mx,my, INTERFACE_RATIO(1), INTERFACE_RATIO(1));
7883 						}
7884 					}
7885 					else
7886 					{
7887 						if(CURCURPOS != 0) {
7888 							CURCURTIME += checked_range_cast<long>(Original_framedelay);
7889 							while(CURCURTIME > CURCURDELAY) {
7890 								CURCURTIME -= CURCURDELAY;
7891 								CURCURPOS++;
7892 							}
7893 						}
7894 
7895 							if (CURCURPOS>7) CURCURPOS=0;
7896 
7897 							surf=scursor[CURCURPOS];
7898 
7899 						if (surf)
7900 						{
7901 							EERIEDrawBitmap(POSX, POSY, INTERFACE_RATIO_DWORD(surf->m_dwWidth),
7902 							                INTERFACE_RATIO_DWORD(surf->m_dwHeight), 0.f, surf, Color::white);
7903 						}
7904 					}
7905 				}
7906 			}
7907 		}
7908 		else //mode system shock
7909 		{
7910 			if (SPECIAL_DRAGINTER_RENDER)
7911 				return;
7912 
7913 			if(FlyingOverIO||DRAGINTER)
7914 			{
7915 				fHighLightAng+=(float)(FrameDiff*0.5f);
7916 
7917 				if(fHighLightAng>90.f) fHighLightAng=90.f;
7918 
7919 				float fHLight	= 100.f*sin(radians(fHighLightAng));
7920 				iHighLight = checked_range_cast<int>(fHLight);
7921 			}
7922 			else
7923 			{
7924 				fHighLightAng=0.f;
7925 				iHighLight = 0;
7926 			}
7927 
7928 			if(TRUE_PLAYER_MOUSELOOK_ON && config.video.showCrosshair) {
7929 				if(!(player.Interface & (INTER_COMBATMODE | INTER_NOTE | INTER_MAP))) {
7930 
7931 					CURCURPOS = 0;
7932 
7933 					surf = pTCCrossHair ? pTCCrossHair : ITC.Get("target_off");
7934 
7935 					if(surf) {
7936 
7937 						GRenderer->SetRenderState(Renderer::AlphaBlending, true);
7938 						GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
7939 
7940 						float POSX = DANAECENTERX - surf->m_dwWidth * .5f;
7941 						float POSY = DANAECENTERY - surf->m_dwHeight * .5f;
7942 
7943 						EERIEDrawBitmap(POSX, POSY, float(surf->m_dwWidth),
7944 						                float(surf->m_dwHeight), 0.f, surf, Color::gray(.5f));
7945 
7946 						GRenderer->SetRenderState(Renderer::AlphaBlending, false);
7947 					}
7948 				}
7949 			}
7950 		}
7951 	}
7952 }
7953 
ARX_INTERFACE_RenderCursor(long flag)7954 void ARX_INTERFACE_RenderCursor(long flag)
7955 {
7956 	ARX_INTERFACE_RenderCursorInternal(flag);
7957 
7958 	// Ensure filtering settings are restored in all cases
7959 	if (!SPECIAL_DRAGINTER_RENDER)
7960 	{
7961 		GRenderer->GetTextureStage(0)->SetMinFilter(TextureStage::FilterLinear);
7962 		GRenderer->GetTextureStage(0)->SetMagFilter(TextureStage::FilterLinear);
7963 		GRenderer->GetTextureStage(0)->SetWrapMode(TextureStage::WrapRepeat);
7964 	}
7965 }
7966