WorldSim  inDev
2D tile-based sandbox RPG with procedurally generated fantasy world simulator 🌏
Menu_AdventureMode.hpp
Go to the documentation of this file.
1 #pragma once
2 #ifndef WORLDSIM_MENU_ADVENTUREMODE_HPP
3 #define WORLDSIM_MENU_ADVENTUREMODE_HPP
4 
5 #include "World_Viewer.hpp"
6 
7 /* Menu_AdventureMode.hpp
8  #include "Menu_AdventureMode.hpp"
9 
10  Adventure mode menu. The player can select a character and play as them.
11  This class contains the code for the Adventure Mode GUI.
12 */
13 
14 //PLAYER INVENTORY
15 // NPCs only have a list of items in their inventory.
16 // However the player gets a grid which saves the position of items
17 // The grid is 10*10. I think it's doubtful that a player will need more than
18 // 100 inventory slots.
19 
20 // Stores the description, index, and interaction id
21 
22 
23 #include "Recipe.hpp"
24 
25 class Menu_Crafting: public GUI_Interface
26 {
27  Vector <Item*> vItem;
28  Vector <Recipe*> vRecipe;
29 
30  int selectedRecipe;
31 
32  public:
33 
35  {
36  selectedRecipe=0;
37  vItem.reserve(100);
38  vRecipe.reserve(100);
39  }
41  {
42  }
43 
44  void build()
45  {
46  selectedRecipe=0;
47 
48  //check inventory grid.
49  for (int _y=0;_y<10;++_y)
50  {
51  for (int _x=0;_x<10;++_x)
52  {
53  if (inventoryGrid[_x][_y]!=0)
54  {
55  vItem.push(inventoryGrid[_x][_y]);
57  }
58  }
59  }
60  vRecipe.clear();
61 
62  auto vValidRecipe = recipeManager.getValidRecipes();
63  // Render the valid recipes.
64  for (int i=0;i<vValidRecipe->size();++i)
65  {
66  vRecipe.push((*vValidRecipe)(i));
67  }
68 
69  }
70 
71  void /* GUI_Interface */ render()
72  {
73  Renderer::placeColour4a(150,150,250,250,panelX1+240,panelY1+40,panelX2-20,panelY2-20);
74  font8x8.drawText("Available recipes:",panelX1+250,(panelY2-40),panelX1+500,(panelY2-50),false,true);
75 
76  if (vRecipe.size() > 0)
77  {
78  Renderer::placeColour4a(180,180,180,255,panelX1+250,(panelY2-50)-(selectedRecipe*10),panelX1+600,(panelY2-50)-((selectedRecipe+1)*10));
79  }
80  for (int i=0;i<vRecipe.size();++i)
81  {
82  font8x8.drawText(vRecipe(i)->getName(),panelX1+250,(panelY2-50)-(i*10),panelX1+500,(panelY2-50)-((i+1)*10),false,true);
83  }
84  }
85 
86  bool /* GUI_Interface */ mouseEvent (Mouse* _mouse)
87  {
88  // Scroll up and down interaction select
89  if (_mouse->isWheelDown)
90  {
91  ++selectedRecipe;
92  if (selectedRecipe>=vRecipe.size()) {selectedRecipe=0;}
93  _mouse->isWheelDown=false;
94  _mouse->isWheelUp=false;
95  }
96  else if (_mouse->isWheelUp)
97  {
98  --selectedRecipe;
99  if (selectedRecipe<0) { selectedRecipe=vRecipe.size()-1; }
100  _mouse->isWheelDown=false;
101  _mouse->isWheelUp=false;
102  }
103  // MAKE RECIPE
104  if (_mouse->isLeftClick)
105  {
106  recipeManager.makeRecipe(playerCharacter, selectedRecipe);
107 
108  _mouse->isLeftClick=false;
109  return true;
110  }
111 
112  return false;
113  }
114 
115 };
116 
117 
118 // Finally getting around to breaking the Menu_AdventureMode into some submenus.
119 // Currently interactions are 1:1. I want an item to have multiple possible interactions with an object.
120 // For example log->ground could be "build campfire" or "build wall".
121 // This should also allow us to more easily sort interactions by priority.
122 class InteractManager: public GUI_Interface
123 {
124  int selectedInteraction;
125  Wildcat::Font* font;
126 
127  struct Interaction /* Stores the description of the interaction and all indexing */
128  {
129  std::string description;
130  int vType; /* 0 = generic, 1 = Item, 2 = Character, 3 = Creature, 4 = terrain */
131  int vIndex; /* Index in the vector of the object. */
132  int interactID; /* Indicates the subtype of interaction (stab/slash/etc). */
133 
134  Interaction( std::string _description, int _vType, int _vIndex, int _interactID )
135  {
136  description=_description;
137  vType = _vType;
138  vIndex = _vIndex;
139  interactID = _interactID;
140  }
141  };
142 
143  public:
144 
145  unsigned long int x,y; /* Tile which the player wants to interact on */
147 
148  Item * sourceItem; /* Item the player is using. 0 = unarmed */
149 
150  // All interactions need to be kept sorted into their object categories.
151  Vector <WorldObject*> vGeneric;
152  Vector <Item*> vItem;
153  Vector <Character*> vCharacter;
154  Vector <Creature*> vCreature;
155 
156  Vector <Interaction*> vInteraction;
157 
158  //Index lookup.
159 
161  {
164  localSelected=0;
165  sourceItem=0;
166  selectedInteraction = 0;
167 
168  font = &font8x8;
169  }
170 
171  void clear()
172  {
175  localSelected=0;
176  sourceItem=0;
177  selectedInteraction = 0;
178  }
179 
180  bool /* GUI_Interface */ keyboardEvent (Keyboard* _keyboard)
181  {
182  if ( _keyboard->isPressed(Keyboard::UP) )
183  {
184  --selectedInteraction;
185  if (selectedInteraction<0) { selectedInteraction=vInteraction.size()-1; }
186  return true;
187  }
188  else if ( _keyboard->isPressed(Keyboard::DOWN) )
189  {
190  ++selectedInteraction;
191  if (selectedInteraction>=vInteraction.size()) {selectedInteraction=0;}
192  return true;
193  }
194 
195  return false;
196  }
197 
198  // GUI INTERFACE
199  bool /* GUI_Interface */ mouseEvent (Mouse* _mouse)
200  {
201 
202  // Scroll up and down interaction select
203  if (_mouse->isWheelDown)
204  {
205  ++selectedInteraction;
206  if (selectedInteraction>=vInteraction.size()) {selectedInteraction=0;}
207  _mouse->isWheelDown=false;
208  _mouse->isWheelUp=false;
209  }
210  else if (_mouse->isWheelUp)
211  {
212  --selectedInteraction;
213  if (selectedInteraction<0) { selectedInteraction=vInteraction.size()-1; }
214  _mouse->isWheelDown=false;
215  _mouse->isWheelUp=false;
216  }
217 
218  else if (_mouse->isLeftClick)
219  {
220  if (sourceItem==0)
221  {
222  sourceItem = &itemHand;
224  }
225 
226 
227  std::cout<<"Using interaction: "<<vInteraction(selectedInteraction)->description<<".\n";
228 
229 
230  Interaction* _interaction = vInteraction(selectedInteraction);
231  int selectedVector = _interaction->vType;
232  int selectedIndex = _interaction->vIndex;
233  int interactionType = _interaction->interactID;
234 
235  if ( selectedVector == 0 ) /* generic */
236  {
237  sourceItem->interact(vGeneric(selectedIndex),interactionType);
238  }
239  else if ( selectedVector == 1 ) /* Item */
240  {
241  sourceItem->interact(vItem(selectedIndex),interactionType);
242  }
243  else if ( selectedVector == 2 ) /* Character */
244  {
245  sourceItem->interact(vCharacter(selectedIndex),interactionType);
246  }
247  else if ( selectedVector == 3 ) /* Creature */
248  {
249  sourceItem->interact(vCreature(selectedIndex),interactionType);
250  }
251  else if ( selectedVector == 4 ) /* Terrain */
252  {
253  std::cout<<"Terrain interaction\n";
254  sourceItem->interact(localSelected,interactionType);
255  }
256 
257  _mouse->isLeftClick=false;
258  return true;
259  }
260 
261  return false;
262  }
263 
264  // Take the current tile and copy all objects
265  // Return false if there's nothing to interact with.
266  bool build(Item* _sourceItem, unsigned long int _x, unsigned long int _y)
267  {
268  if (playerCharacter == 0)
269  {
270  return false;
271  }
272 
273  vGeneric.clear();
274  vItem.clear();
275  vCharacter.clear();
276  vCreature.clear();
277  vInteraction.deleteAll();
278 
279  x=_x;
280  y=_y;
281  localSelected=world(x,y,playerCharacter->isUnderground);
282 
283  // if (playerCharacter->isUnderground)
284  // {
285  // }
286 
287 
288 
289  sourceItem = _sourceItem;
290 
291  std::cout<<"Building interactions for: "<<x<<", "<<y<<".\n";
292  if (sourceItem ==0 ) // HAND INTERACTIONS
293  {
294  // ADD TERRAIN INTERACTION
295  vInteraction.push( new Interaction ("Punch ground",4,0,0) );
296 
297  for (int i=0; i<localSelected->vObjectGeneric.size();++i)
298  {
299  auto vInteract = itemHand.getInteractNames(localSelected->vObjectGeneric(i));
300 
301  if ( vInteract !=0 )
302  {
303  for (int i2=0;i2<vInteract->size();++i2)
304  {
305  vGeneric.push(localSelected->vObjectGeneric(i2));
306  vInteraction.push( new Interaction ((*vInteract)(i2),0,i,i2) );
307  }
308  }
309  }
310  for (int i=0; i<localSelected->vItem.size();++i)
311  {
312  vGeneric.push(localSelected->vItem(i));
313  vInteraction.push( new Interaction ("Punch "+localSelected->vItem(i)->getName(),0,i,0) );
314  }
315  for (int i=0; i<localSelected->vCharacter.size();++i)
316  {
317  vGeneric.push(localSelected->vCharacter(i));
318  vInteraction.push( new Interaction ("Punch "+localSelected->vCharacter(i)->getName(),0,i,0) );
319  }
320  for (int i=0; i<localSelected->vCreature.size();++i)
321  {
322  vGeneric.push(localSelected->vCreature(i));
323  vInteraction.push( new Interaction ("Punch "+localSelected->vCreature(i)->getName(),0,i,0) );
324  }
325 
326  }
327  else
328  {
329  // ADD TERRAIN INTERACTION
330  auto vInteractTerrain = sourceItem->getInteractNames(localSelected);
331  if ( vInteractTerrain !=0 )
332  {
333  for (int i2=0;i2<vInteractTerrain->size();++i2)
334  {
335  vInteraction.push( new Interaction ((*vInteractTerrain)(i2),4,0,i2) );
336  }
337  }
338 
339  for (int i=0; i<localSelected->vObjectGeneric.size();++i)
340  {
341  auto vInteract = sourceItem->getInteractNames(localSelected->vObjectGeneric(i));
342  auto target = localSelected->vObjectGeneric(i);
343 
344  if ( vInteract !=0 )
345  {
346  for (int i2=0;i2<vInteract->size();++i2)
347  {
348  vGeneric.push(localSelected->vObjectGeneric(i2));
349  vInteraction.push( new Interaction ((*vInteract)(i2),0,i,i2) );
350  }
351  }
352  }
353  for (int i=0; i<localSelected->vItem.size();++i)
354  {
355  auto vInteract = sourceItem->getInteractNames(localSelected->vItem(i));
356 
357  if ( vInteract !=0 )
358  {
359  for (int i2=0;i2<vInteract->size();++i2)
360  {
361  vItem.push(localSelected->vItem(i2));
362  vInteraction.push( new Interaction ((*vInteract)(i2),1,i,i2) );
363  }
364  }
365  }
366  for (int i=0; i<localSelected->vCharacter.size();++i)
367  {
368  auto vInteract = sourceItem->getInteractNames(localSelected->vCharacter(i));
369 
370  if ( vInteract !=0 )
371  {
372  for (int i2=0;i2<vInteract->size();++i2)
373  {
374  vCharacter.push(localSelected->vCharacter(i2));
375  vInteraction.push( new Interaction ((*vInteract)(i2),2,i,i2) );
376  }
377  }
378  }
379  for (int i=0; i<localSelected->vCreature.size();++i)
380  {
381  auto vInteract = sourceItem->getInteractNames(localSelected->vCreature(i));
382 
383  if ( vInteract !=0 )
384  {
385  for (int i2=0;i2<vInteract->size();++i2)
386  {
387  vCreature.push(localSelected->vCreature(i2));
388  vInteraction.push( new Interaction ((*vInteract)(i2),3,i,i2) );
389  }
390  }
391  }
392  }
393 
394 
395  return (vInteraction.size() > 0);
396  }
397 
398  void /* GUI_Interface */ render()
399  {
400  // Render background and selection panels.
401  Renderer::placeColour4a(120,120,120,255,panelX1+250,panelY2,panelX1+600,(panelY2)-(vInteraction.size()*10));
402  Renderer::placeColour4a(180,180,180,255,panelX1+250,panelY2-(selectedInteraction*10),panelX1+600,panelY2-((selectedInteraction+1)*10));
403 
404  for (int i=0;i<vInteraction.size();++i)
405  {
406  font8x8.drawText(vInteraction(i)->description,panelX1+250,(panelY2)-(i*10),panelX1+500,(panelY2)-(i*10)-10,false,true);
407  //font8x8.drawText("("+DataTools::toString(useItem->interactTime(localTileSelected->vItem(i)))+" sec)",panelX1+500,(panelY2)-((i+j)*10),panelX1+600,(panelY2)-((i+j)*10)-10,false,true);
408  }
409  }
410 
411 
412 };
414 
415 class Menu_AdventureMode: public GUI_Interface
416 {
417  private:
418  GUI_Manager guiManager;
419 
420  /* Colours / theme. */
421  ColourRGB <unsigned char> cNormal;
422  ColourRGB <unsigned char> cSelected;
423  ColourRGB <unsigned char> cDropPanel;
424  ColourRGB <unsigned char> cHighlight;
425 
426  Wildcat::Font* font;
427 
428  /* Texture to draw in the background of this menu. */
429  Texture* backgroundTexture;
430 
431 
432  /* Button to center camera on current player */
433  GUI_Button buttonCenterCamera;
434 
435  /* Button to toggle sneaking - SNK */
436  GUI_Button buttonSneak;
437 
438 
439  /* Button to view inventory */
440  GUI_Button buttonInventory;
441 
442 
443  /* Button to reveal map (debug) */
444  GUI_Button buttonRevealMap;
445 
446  /* Button to view manual */
447  // Very basic manual for now. Future manual should have stuff like bestiary, alchemy instructions,
448  // crafting instructions, etc.
449  GUI_Button buttonManual;
450  bool manualActive;
451 
452  /* Button to view character sheet - CHR */
453  GUI_Button buttonCharacterSheet;
454 
455  /* Button to view craftomg menu - CFT */
456  GUI_Button buttonCrafting;
457  bool craftingMenuActive;
458  Menu_Crafting menuCrafting;
459 
460 
461 
462  // Render conversation menu
463  bool conversationActive;
464  Character* conversationCharacter;
465 
466  // Render character sheet
467  bool characterSheetActive;
468 
469  //Render inventory menu
470  bool inventoryActive;
471  int clickedItemSlot;
472  Vector <Item*> vItemsOnFloor;
473  // Carried item is an item selected by the mouse. The item will follow the cursor.
474  Item* carriedItem;
475 
476 
477  int selectedHotbar;
478  int hoveredInventoryX, hoveredInventoryY;
479 
480  //Render item selection
481  bool itemSelectionActive;
482  unsigned long int tileSelectAbsoluteX, tileSelectAbsoluteY;
483  LocalTile* localTileSelected; /* LocalTile that the player last selected */
484  int nInteractions; /* number of interactions currently in the menu */
485 
486  // Vectors of each object on selected tile, broken down by type.
487  //Vector <Item*> vSelectedTileItems;
488  //Vector <Character*> vSelectedTileCharacter;
489 
490 
491  int selectedItemSlot; /* 0 = interact with terrain */
492  bool subItemSelectionActive;
493  Item* useItem; /* Item to use on target */
494 
495  // CTRL is modifier for inventory menu. Will add 1 of item to inventory, or transfer 1 of item to storage. Or
496  // drop 1 of item.
497  bool holdingCTRL;
498 
499  int mouseX, mouseY;
500 
501  Vector <HasXY2 <unsigned long int> * > * vLineOfFire; /* Vector of tiles to highlight for line of fire overlay */
502 
503  public:
504 
505 
506 
507 
509  {
510  backgroundTexture=&TEX_NEW_GAME_BACKGROUND;
511  font = &font8x8;
512  vLineOfFire=0;
513  }
514 
515  void clearMenus()
516  {
517  if ( conversationActive )
519 
520  manualActive=false;
521  conversationActive=false;
522  characterSheetActive=false;
523  inventoryActive=false;
524  itemSelectionActive=false;
525 
526  // Reset the interact menu.
527  subItemSelectionActive=false;
528  itemSelectionActive=false;
530  localTileSelected=0;
531  selectedItemSlot=0;
532 
533  // Clear previous overlay tiles.
534  for ( int i=0;i<vLineOfFire->size();++i)
535  {
536  world((*vLineOfFire)(i))->shotOverlay=false;
537  }
538  vLineOfFire->deleteAll();
539  delete vLineOfFire;
540  vLineOfFire=new Vector <HasXY2 <unsigned long int> * >;
541 
542  craftingMenuActive=false;
544  }
545 
546  void init()
547  {
548  /* Initialise theme. */
549  cNormal.set(200,200,200);
550  cSelected.set(180,180,180);
551  cDropPanel.set(170,170,170);
552  cHighlight.set(170,170,170);
553 
554  buttonCenterCamera.text="";
555  buttonSneak.text="SNK";
556  buttonSneak.font = font;
557  buttonCenterCamera.setColours(cNormal,cHighlight,0);
558  buttonSneak.setColours(cNormal,cHighlight,0);
559  guiManager.add(&buttonCenterCamera);
560  guiManager.add(&buttonSneak);
561  buttonCenterCamera.active=true;
562  buttonSneak.active=true;
563  buttonCenterCamera.texture = &TEX_GUI_CENTER_CAMERA;
564 
565 
566  buttonInventory.active = true;
567  buttonInventory.text = "INV";
568  buttonInventory.font = font;
569  buttonInventory.setColours(cNormal,cHighlight,0);
570  guiManager.add(&buttonInventory);
571 
572  buttonRevealMap.active = true;
573  buttonRevealMap.text = "RVL";
574  buttonRevealMap.font = font;
575  buttonRevealMap.setColours(cNormal,cHighlight,0);
576  guiManager.add(&buttonRevealMap);
577 
578  buttonManual.active = true;
579  buttonManual.text = "MAN";
580  buttonManual.font = font;
581  buttonManual.setColours(cNormal,cHighlight,0);
582  guiManager.add(&buttonManual);
583 
584  buttonCharacterSheet.active = true;
585  buttonCharacterSheet.text = "CHR";
586  buttonCharacterSheet.font = font;
587  buttonCharacterSheet.setColours(cNormal,cHighlight,0);
588  guiManager.add(&buttonCharacterSheet);
589 
590  buttonCrafting.active = true;
591  buttonCrafting.text = "CFT";
592  buttonCrafting.font = font;
593  buttonCrafting.setColours(cNormal,cHighlight,0);
594  guiManager.add(&buttonCrafting);
595 
596 
597  craftingMenuActive=false;
598 
599  itemSelectionActive=false;
600  tileSelectAbsoluteX=-1;
601  tileSelectAbsoluteY=-1;
602  localTileSelected=0;
603  selectedItemSlot=0;
604  subItemSelectionActive=false;
605  useItem=0;
606  nInteractions=0;
607 
608  characterSheetActive=false;
609 
610  manualActive=false;
611  conversationActive = false;
612  conversationCharacter=0;
613 
614  inventoryActive=false;
615  clickedItemSlot=-1;
616  carriedItem=0;
617  hoveredInventoryX=-1;
618  hoveredInventoryY=-1;
619 
620  holdingCTRL = false;
621 
622  mouseX=0;
623  mouseY=0;
624 
625  selectedHotbar=0;
626 
627  delete vLineOfFire;
628  vLineOfFire= new Vector <HasXY2 <unsigned long int> * >;
629 
630  //Initialise inventory grid.
631  for (int _y=0;_y<10;++_y)
632  {
633  for (int _x=0;_x<10;++_x)
634  {
635  inventoryGrid[_x][_y]=0;
636  }
637  }
638 
639  eventResize();
640  }
641 
642 
643  void render()
644  {
645 
646  if (playerCharacter==0)
647  { return; }
648 
649  /* Render adventure mode interface.
650  Yes it is very messy at the moment, however it works fine and is just a GUI
651  so it doesn't matter too much. */
652 
653 
654  /* Preview world view. */
656 
657  // MESSAGE CONSOLE
658  const int nY = panelY2-panelY1;
659  Renderer::placeColour4a(200,200,250,125,panelX1,panelY1+120,panelX1+220,panelY2);
660  int currentY = panelY2-2;
661  int iMessage = vConsoleMessage.size()-1;
662 
663  int linesDrawn = 0;
664 
665  while (currentY>panelY1+120 && iMessage>=0 && iMessage<vConsoleMessage.size() )
666  {
667  linesDrawn = font8x8.drawText(vConsoleMessage(iMessage),panelX1,currentY,panelX1+220,currentY-38,false,false);
668  --iMessage;
669  currentY-=linesDrawn*9;
670  currentY-=2;
671  }
672 
673  // minimap will give better situational awareness for the player
674  Renderer::placeColour4a(200,200,250,250,panelX1,panelY1,panelX1+220,panelY1+220);
675  font8x8.drawText("Minimap",panelX1,panelY1,panelX1+220,panelY1+220,true,true);
676 
677  // action menu contains all actions which otherwise have hotkeys
678  Renderer::placeColour4a(150,150,150,250,panelX1,panelY1+220,panelX1+220,panelY1+320);
679  font8x8.drawText("Action Menu",panelX1,panelY1+220,panelX1+220,panelY1+320,true,true);
680 
681  // tile info panel outputs information about whatever the player is hovering mouse over
682  Renderer::placeColour4a(150,150,150,250,panelX1,panelY1+320,panelX1+220,panelY1+420);
683  // font8x8.drawText("Tile info",panelX1,panelY1+320,panelX1+220,panelY1+420,true,true);
684 
685  // HOVERED TILE COORDINATES. BOTH ABSOLUTE AND RELATIVE. FOR DEBUGGING.
686  font8x8.drawText(DataTools::toString(worldViewer.hoveredXTile) + ", " +
687  DataTools::toString(worldViewer.hoveredYTile),panelX1,panelY1+210,panelX1+220,panelY1+220,false,true);
688  font8x8.drawText(DataTools::toString(worldViewer.hoveredXTileLocal) + ", " +
689  DataTools::toString(worldViewer.hoveredYTileLocal),panelX1,panelY1+200,panelX1+220,panelY1+210,false,true);
690  font8x8.drawText(DataTools::toString(worldViewer.hoveredAbsoluteX) + ", " +
691  DataTools::toString(worldViewer.hoveredAbsoluteY),panelX1,panelY1+190,panelX1+220,panelY1+200,false,true);
692 
693  // PRINT STUFF ON HOVERED TILE
695  {
697 
698  if (localSelected)
699  {
700  // output terrain type
701  font8x8.drawText(localSelected->getAll(10),panelX1,panelY1+420,panelX1+220,panelY1+320,false,false,false,0,0,0,255,1);
702  }
703 
704 
705 
706  }
707  else
708  {
709  //LocalTile* localSelected=world(worldViewer.hoveredAbsoluteX,worldViewer.hoveredAbsoluteY,playerCharacter->isUnderground);
710  font8x8.drawText("OOB",panelX1,panelY1+410,panelX1+220,panelY1+420,false,true);
711  }
712 
713 
714 
715 
716  if (playerCharacter->thirst > MAX_THIRST - 100)
717  {
718  font8x8.drawText("THIRSTY",panelX1+230,panelY1+230,panelX1+400,panelY1+240,false,true,255,0,0);
719  }
720  if (playerCharacter->hunger > MAX_HUNGER - 100)
721  {
722  font8x8.drawText("HUNGRY",panelX1+230,panelY1+220,panelX1+400,panelY1+230,false,true,255,0,0);
723  }
724  if (playerCharacter->isAlive == false)
725  {
726  font8x8.drawText("RIP (TAB TO EXIT)",panelX1+230,panelY1+210,panelX1+500,panelY1+220,false,true,255,0,0);
727  }
728 
729  //BARS: Health, Stamina, Hunger, Thirst, Energy
730  double barWidth = 220;
731  double hungerWidth = (MAX_HUNGER-playerCharacter->hunger)*(barWidth/MAX_HUNGER);
732  double thirstWidth = (MAX_THIRST-playerCharacter->thirst)*(barWidth/MAX_THIRST);
733  double healthWidth = barWidth-(playerCharacter->maxHealth-playerCharacter->health)*(barWidth/playerCharacter->maxHealth);
734 
735  Renderer::placeColour4a(255,0,0,255,panelX1,panelY1+232,panelX1+healthWidth,panelY1+234);
736  Renderer::placeColour4a(0,0,255,255,panelX1,panelY1+229,panelX1+thirstWidth,panelY1+231);
737  Renderer::placeColour4a(128,64,0,255,panelX1,panelY1+226,panelX1+hungerWidth,panelY1+228);
738  Renderer::placeColour4a(128,128,255,255,panelX1,panelY1+223,panelX1+220,panelY1+225);
739  Renderer::placeColour4a(255,128,0,255,panelX1,panelY1+220,panelX1+220,panelY1+222);
740 
741  guiManager.render();
742 
743  // DATE
744  //Renderer::placeColour4a(150,150,150,255,panelX2-208,panelY2-20,panelX2,panelY2-10);
745  std::string strDate = world.calendar.toString();
746  font8x8.drawText("DATE: "+strDate,panelX1,panelY1+235,panelX1+220,panelY1+245, true, true);
747 
748  //Draw hotbar
749  int currentX2 = panelX1 + 240;
750  for (int i=0;i<10;++i)
751  { Renderer::placeColour4a(120,120,120,250,currentX2,panelY1+5,currentX2+32,panelY1+37);
752  if ( inventoryGrid[i][0] != 0 )
753  { Renderer::placeTexture4(currentX2,panelY1+5,currentX2+32,panelY1+37, inventoryGrid[i][0]->currentTexture(), false);
754  }
755 
756  if ( i==selectedHotbar )
757  { Renderer::placeTexture4(currentX2,panelY1+5,currentX2+32,panelY1+37, &TEX_GUI_TILE_SELECTION, false);
758  }
759 
760  currentX2+=34;
761  }
762 
763  // Render item selection
764  if (itemSelectionActive && localTileSelected != 0)
765  {
766 
767  // New system: interactManager
768  interactManager.render();
769 
770  nInteractions = localTileSelected->vItem.size() + localTileSelected->vCharacter.size() + localTileSelected->vCreature.size() + localTileSelected->vObjectGeneric.size() + 1;
771 
772  }
773 
774  // Render manual page
775  if (manualActive)
776  {
777  Renderer::placeColour4a(150,150,250,250,panelX1+240,panelY1+40,panelX2-20,panelY2-20);
778  linesDrawn = font8x8.drawText(ADVENTURE_MODE_MANUAL,panelX1+250,panelY1+45,panelX2-25,panelY2-25,false,false);
779  }
780 
781  // Render crafting menu
782  if (craftingMenuActive)
783  {
784  menuCrafting.render();
785  }
786 
787 
788  //Render character sheet
789  if (characterSheetActive)
790  {
791  Renderer::placeColour4a(150,150,250,250,panelX1+240,panelY1+40,panelX2-20,panelY2-20);
792  linesDrawn = font8x8.drawText("CHARACTER SHEET\nSkills:\nFishing: "+DataTools::toString((int)playerCharacter->skillFishing),panelX1+250,panelY1+45,panelX2-25,panelY2-25,false,false);
793  }
794 
795  // Render conversation menu
796  if (conversationActive && conversationCharacter != 0)
797  {
798  Renderer::placeColour4a(30,140,40,250,panelX1+235,panelY1+40,panelX2-15,panelY2-10);
799 
800  Renderer::placeColour4a(150,150,250,250,panelX1+240,panelY1+40,panelX2-162,panelY2-220);
801  linesDrawn = font8x8.drawText(playerCharacter->getFullName()+" talks to "+conversationCharacter->getFullName()+".\n\n["+playerCharacter->getFullName()+"]: COLONEL, WHAT'S A CONVERSATION SYSTEM DOING HERE?\n["+conversationCharacter->getFullName()+"]: Snake, remember what De Gaulle said \"The graveyards are full of indispensable men.\" Snake, you're all alone and surrounded by bad guys. Try to be careful and avoid getting into a fight whenever you can.\n["+playerCharacter->getFullName()+"]: I FEEL ASLEEP.\n\n(Press ESC to exit)",panelX1+242,panelY1+42,panelX2-164,panelY2-222,false,false);
802 
803  Renderer::placeColour4a(150,150,250,250,panelX2-160,panelY1+40,panelX2-20,panelY2-220);
804  linesDrawn = font8x8.drawText("WE\nMORROWIND\nNOW",panelX2-158,panelY1+42,panelX2-22,panelY2-222,false,false);
805 
806  Renderer::placeColour4a(150,150,250,250,panelX1+350,panelY2-210,panelX2-130,panelY2-20);
807  linesDrawn = font8x8.drawText("Disposition: Solid",panelX1+355,panelY2-215,panelX2-135,panelY2-25,false,false);
808 
809 
810  Renderer::placeTexture4(panelX1+240, panelY2-160, panelX1+340, panelY2-60, &TEX_PORTRAIT_SNEK, true);
811  Renderer::placeTexture4(panelX2-120, panelY2-160, panelX2-20, panelY2-60, &TEX_PORTRAIT_LING, true);
812  }
813 
814  // Render inventory menu
815  // Yes this will need to be moved into its own file at some point,
816  // but hey who cares as long as it works.
817  if (inventoryActive)
818  {
819  // background panels for inventory menu.
820  Renderer::placeColour4a(30,140,40,250,panelX1+235,panelY1+35,panelX2-15,panelY2-10);
821  Renderer::placeColour4a(150,150,250,250,panelX1+240,panelY1+40,panelX2-20,panelY2-220);
822  Renderer::placeColour4a(150,150,250,250,panelX1+350,panelY2-210,panelX2-130,panelY2-20);
823 
824  // Put items on player to interact
825  Renderer::placeTexture4(panelX1+350,panelY2-210,panelX2-130,panelY2-20, &TEX_NPC, false);
826 
827  hoveredInventoryX=-1;
828  hoveredInventoryY=-1;
829 
830  // render inventory slots
831  int inventoryY = panelY2-250;
832  int currentFloorItem = 0;
833 
834  for (int row = 0;row<12;++row)
835  { int currentX = panelX1+250;
836  for (int i=0;i<10;++i)
837  {
838  Renderer::placeColour4a(120,120,120,250,currentX,inventoryY,currentX+32,inventoryY-32);
839 
840  if (mouseX >= currentX && mouseX <= currentX+32
841  && mouseY >=inventoryY-32 && mouseY <= inventoryY)
842  {
843  hoveredInventoryX = i;
844  hoveredInventoryY = row;
845  }
846 
847  if (row < 10 && i < 10 && inventoryGrid[i][row]!=0)
848  {
849  //Renderer::placeColour4a(120,120,120,250,currentX,inventoryY,currentX+32,inventoryY-32);
850  Renderer::placeTexture4(currentX,inventoryY-32,currentX+32,inventoryY, inventoryGrid[i][row]->currentTexture(), false);
851  }
852 
853  // floor inventory
854  if (row == 10 || row == 11 )
855  {
856  if ( currentFloorItem < vItemsOnFloor.size() && vItemsOnFloor(currentFloorItem) != carriedItem )
857  {
858  Renderer::placeTexture4(currentX,inventoryY-32,currentX+32,inventoryY, vItemsOnFloor(currentFloorItem)->currentTexture(), false);
859  ++currentFloorItem;
860  }
861  }
862 
863  if ( row==0 )
864  {
865  font8x8.drawText(DataTools::toString(i),currentX,inventoryY,currentX+32,inventoryY-32,true,true);
866  }
867  currentX += 34;
868  }
869  inventoryY -= 34;
870  // make a gap for floor inventory
871  if ( row == 9) {inventoryY -= 5;}
872  }
873 
874  inventoryY = panelY2-250;
875 
876  for (int row = 0;row<12;++row)
877  { int currentX = panelX1+650;
878  for (int i=0;i<10;++i)
879  {
880  Renderer::placeColour4a(120,120,120,250,currentX,inventoryY,currentX+32,inventoryY-32);
881  if ( row==0 )
882  {
883  font8x8.drawText(DataTools::toString(i),currentX,inventoryY,currentX+32,inventoryY-32,true,true);
884  }
885  currentX += 34;
886  }
887  inventoryY -= 34;
888  if ( row == 9) {inventoryY -= 5;}
889  }
890 
891  // Render text
892  // We render the stats for 2 items: The item the player has selected,
893  // and the item the player is hovering over. This allow easy comparison
894  // of 2 items.
895  std::string carriedItemStats = "";
896  if ( carriedItem )
897  {
898  carriedItemStats = carriedItem->getName();
899  }
900  std::string hoveredItemStats = "";
901  if ( hoveredInventoryX >= 0 && hoveredInventoryX < 10
902  && hoveredInventoryY >= 0 && hoveredInventoryY < 10)
903  {
904  if (inventoryGrid[hoveredInventoryX][hoveredInventoryY] )
905  {
906  hoveredItemStats = inventoryGrid[hoveredInventoryX][hoveredInventoryY]->getName();
907  }
908 
909  }
910 
911  font8x8.drawText("Inventory", panelX1 + 250,panelY2-230,panelX1 + 450,panelY2-250,true,true);
912  font8x8.drawText("Storage", panelX1 + 650,panelY2-230,panelX1 + 850,panelY2-250,true,true);
913  font8x8.drawText("Carried stats:\n "+carriedItemStats, panelX1+350,panelY2-210,panelX1+(panelNX/2) ,panelY2-25,false,false);
914  font8x8.drawText("Hovered stats\n "+hoveredItemStats, panelX1+(panelNX/2),panelY2-210,panelX2-130,panelY2-25,false,false);
915 
916  // Render carried item
917  if ( carriedItem != 0)
918  {
919  Renderer::placeTexture4(mouseX,mouseY-32,mouseX+32,mouseY, carriedItem->currentTexture(), false);
920  }
921  }
922 
923 
924  // Draw a line of fire overlay so the player can see the path his missile will take.
926  {
927  // Clear previous overlay tiles.
928  for ( int i=0;i<vLineOfFire->size();++i)
929  {
930  world((*vLineOfFire)(i))->shotOverlay=false;
931  }
932  vLineOfFire->deleteAll();
933  delete vLineOfFire;
934  vLineOfFire=new Vector <HasXY2 <unsigned long int> * >;
935 
936  //Build new line of sight overlay.
937  // Diagonals are allowed for the first move, but not for subsequent moves.
938  unsigned long int shootDistance = DataTools::chebyshevDistance(playerCharacter->fullX, playerCharacter->fullY, worldViewer.hoveredAbsoluteX, worldViewer.hoveredAbsoluteY);
939 
940  //Only draw the overlay if the player is hovering the mouse more than 1 tile away, but not too far away.
941  if ( shootDistance > 1 && shootDistance <= MAX_VIEW_RANGE )
942  {
943  // Raytrace
945 
946 
947  for ( int i=0;i<vLineOfFire->size();++i)
948  {
949  world((*vLineOfFire)(i))->shotOverlay=true;
950  }
951 
952  }
953  }
954 
955  }
956 
957  void logicTick()
958  {
959  return;
960  }
961 
962  bool keyboardEvent (Keyboard* _keyboard)
963  {
964  // ESCAPE - Close all submenus and go back to main game.
965  // If all submenus are already closed, bring up main menu.
966  if(_keyboard->isPressed(Keyboard::ESCAPE)) /* Flush console. */
967  {
968  clearMenus();
969  _keyboard->keyUp(Keyboard::ESCAPE);
970  }
971  // Interactionmanager
972  else if (itemSelectionActive && localTileSelected != 0 && interactManager.keyboardEvent(_keyboard))
973  {
974  return true;
975  }
976 
977  // SPACE = TALK, INTERACT
978  if(_keyboard->isPressed(Keyboard::SPACE) && conversationActive==false)
979  {
980 
982  if ( wl != 0 )
983  {
984  // wl->moveObject(playerCharacter,playerCharacter->x,playerCharacter->y-1);
985  // worldViewer.setCenterTile(playerCharacter->worldX, playerCharacter->worldY, playerCharacter->x, playerCharacter->y);
986  // world.updateMaps();
987  // playerCharacter->updateKnowledge();
988 
989 
990 
991  Vector <Character*> * vNearbyCharacter = wl->getAdjacentCharacters(playerCharacter->x,playerCharacter->y);
992 
993  conversationCharacter = 0;
994 
995  if ( vNearbyCharacter != 0)
996  {
997  for (int i=0;i<vNearbyCharacter->size(); ++i)
998  {
999  std::cout<<(*vNearbyCharacter)(i)->getFullName()<<".\n";
1000  if ((*vNearbyCharacter)(i)!=playerCharacter)
1001  {
1002  conversationCharacter = (*vNearbyCharacter)(i);
1003  }
1004  }
1005  }
1006 
1007  if (conversationCharacter != 0)
1008  {
1009  std::cout<<playerCharacter->getFullName()<<" talks to "<<conversationCharacter->getFullName()<<".\n";
1010  conversationActive=true;
1011  }
1012  }
1013 
1014  _keyboard->keyUp(Keyboard::SPACE);
1015  }
1016 
1017  // I = TOGGLE INVENTORY
1018  if(_keyboard->isPressed(Keyboard::I) || _keyboard->isPressed(Keyboard::i))
1019  {
1020  inventoryActive = !inventoryActive;
1021 
1022  // build list of items on the floor
1023  if (inventoryActive)
1024  {
1025  vItemsOnFloor.clear();
1027  if ( wl != 0 )
1028  {
1029  for (int i=0;i<wl->vItem.size();++i)
1030  {
1031  if (wl->vItem(i)->x == playerCharacter->x && wl->vItem(i)->y == playerCharacter->y)
1032  {
1033  vItemsOnFloor.push(wl->vItem(i));
1034  }
1035  }
1036  }
1037  }
1038 
1039  _keyboard->keyUp(Keyboard::I);
1040  _keyboard->keyUp(Keyboard::i);
1041  }
1042 
1043  // E = Use item. Currently context-sensitive. In future there might be a menu of choices.
1044  if(_keyboard->isPressed(Keyboard::E) || _keyboard->isPressed(Keyboard::e))
1045  {
1046  itemSelectionActive = !itemSelectionActive;
1047 
1048 
1049  // Clear previous overlay tiles.
1050  for ( int i=0;i<vLineOfFire->size();++i)
1051  {
1052  world((*vLineOfFire)(i))->shotOverlay=false;
1053  }
1054  vLineOfFire->deleteAll();
1055  delete vLineOfFire;
1056  vLineOfFire=new Vector <HasXY2 <unsigned long int> * >;
1057 
1058  if ( selectedHotbar >= 0 && selectedHotbar < 10 )
1059  {
1060  useItem = inventoryGrid[selectedHotbar][0];
1061  }
1062 
1063  worldViewer.showHoveredTile = itemSelectionActive;
1064  localTileSelected=0;
1065  subItemSelectionActive=false;
1066  selectedItemSlot=0;
1067 
1068  _keyboard->keyUp(Keyboard::E);
1069  _keyboard->keyUp(Keyboard::e);
1070  }
1071 
1072  // Pay respects
1073  if(_keyboard->isPressed(Keyboard::F) || _keyboard->isPressed(Keyboard::f))
1074  {
1075  if (playerCharacter != 0)
1076  {
1078  if ( wl != 0 )
1079  {
1080  wl->shotOverlay=true;
1081  }
1082  }
1083 
1084 
1085  _keyboard->keyUp(Keyboard::F);
1086  _keyboard->keyUp(Keyboard::f);
1087  }
1088 
1089  // Disable keyboard if we're in a menu.
1090  if (itemSelectionActive || subItemSelectionActive || manualActive || conversationActive || inventoryActive)
1091  {
1092  _keyboard->clearAll();
1093  return true;
1094  }
1095 
1096  // TAB will switch between adventure mode and god mode.
1097  // Make sure to relinquish control of character.
1098  if(_keyboard->isPressed(Keyboard::TAB))
1099  {
1100  playerCharacter=0;
1102 
1103  //menuWorldSimulator.active = true;
1104 
1105 
1107 
1108  _keyboard->keyUp(Keyboard::TAB);
1109  }
1110 
1111  if(_keyboard->isPressed(Keyboard::RIGHT) || _keyboard->isPressed(Keyboard::D) || _keyboard->isPressed(Keyboard::d))
1112  {
1114  if ( wl != 0 )
1115  {
1116  if ( playerCharacter->isAlive )
1117  {
1118 
1121  world.updateMaps();
1123 
1125  else { world.incrementTicksBacklog(1); }
1126  }
1127  else
1128  {
1129  //Console ("BOI U DED, U AINT GOIN NOWHERE");
1130  }
1131 
1132  }
1133 
1134  _keyboard->keyUp(Keyboard::RIGHT);
1135  _keyboard->keyUp(Keyboard::D);
1136  _keyboard->keyUp(Keyboard::d);
1137  RENDER_NEXT_FRAME=true;
1138  }
1139  if(_keyboard->isPressed(Keyboard::LEFT) || _keyboard->isPressed(Keyboard::A) || _keyboard->isPressed(Keyboard::a))
1140  {
1142  if ( wl != 0 )
1143  {
1144  if (playerCharacter->isAlive)
1145  {
1148  world.updateMaps();
1150 
1152  else { world.incrementTicksBacklog(1); }
1153  }
1154  else
1155  {
1156  //Console ("BOI U DED, U AINT GOIN NOWHERE");
1157  }
1158  }
1159 
1160  _keyboard->keyUp(Keyboard::LEFT);
1161  _keyboard->keyUp(Keyboard::A);
1162  _keyboard->keyUp(Keyboard::a);
1163  RENDER_NEXT_FRAME=true;
1164  }
1165  if(_keyboard->isPressed(Keyboard::UP) || _keyboard->isPressed(Keyboard::W) || _keyboard->isPressed(Keyboard::w))
1166  {
1168  if ( wl != 0 )
1169  {
1170  if (playerCharacter->isAlive)
1171  {
1174  world.updateMaps();
1176 
1178  else { world.incrementTicksBacklog(1); }
1179  }
1180  else
1181  {
1182  //Console ("BOI U DED, U AINT GOIN NOWHERE");
1183  }
1184  }
1185  _keyboard->keyUp(Keyboard::UP);
1186  _keyboard->keyUp(Keyboard::W);
1187  _keyboard->keyUp(Keyboard::w);
1188  RENDER_NEXT_FRAME=true;
1189  }
1190  if(_keyboard->isPressed(Keyboard::DOWN) || _keyboard->isPressed(Keyboard::S) || _keyboard->isPressed(Keyboard::s))
1191  {
1193  if ( wl != 0 )
1194  {
1195  if (playerCharacter->isAlive)
1196  {
1199  world.updateMaps();
1201 
1203  else { world.incrementTicksBacklog(1); }
1204  }
1205  else
1206  {
1207  //Console ("BOI U DED, U AINT GOIN NOWHERE");
1208  }
1209  }
1210  _keyboard->keyUp(Keyboard::DOWN);
1211  _keyboard->keyUp(Keyboard::S);
1212  _keyboard->keyUp(Keyboard::s);
1213  RENDER_NEXT_FRAME=true;
1214  }
1215  // PERIOD = WAIT
1216  if(_keyboard->isPressed(Keyboard::PERIOD))
1217  {
1219  _keyboard->keyUp(Keyboard::PERIOD);
1220  RENDER_NEXT_FRAME=true;
1221  }
1222 
1223  // SHIFT+, and SHIFT+.
1224  // Move view up or down
1225  // Basically just toggles subterranean mode right now.
1226  if(_keyboard->isPressed(Keyboard::RIGHT_CHEVRON))
1227  {
1228  if (playerCharacter)
1229  {
1230  // update LOS backlog because it currently can't handle layers.
1231  while ( playerCharacter->updateKnowledgeIdle() ) {}
1232 
1235  {
1236  if (wl->moveDown(playerCharacter))
1237  {
1240  }
1241  else
1242  {
1243  Console("There's no way down here");
1244  }
1245  }
1246 
1247  }
1248  _keyboard->keyUp(Keyboard::RIGHT_CHEVRON);
1249  _keyboard->keyUp(Keyboard::LEFT_CHEVRON);
1250  }
1251  // Move view up or down
1252  if(_keyboard->isPressed(Keyboard::LEFT_CHEVRON))
1253  {
1254  if (playerCharacter)
1255  {
1256  // update LOS backlog because it currently can't handle layers.
1257  while ( playerCharacter->updateKnowledgeIdle() ) {}
1258 
1261  {
1262  if (wl->moveUp(playerCharacter))
1263  {
1266  }
1267  else
1268  {
1269  Console("There's no way up here");
1270  }
1271  }
1272 
1273  }
1274  _keyboard->keyUp(Keyboard::RIGHT_CHEVRON);
1275  _keyboard->keyUp(Keyboard::LEFT_CHEVRON);
1276  }
1277  // Move view up or down
1278  if(_keyboard->isPressed(Keyboard::Q) || _keyboard->isPressed(Keyboard::q))
1279  {
1280  if (playerCharacter)
1281  {
1282  // update LOS backlog because it currently can't handle layers.
1283  while ( playerCharacter->updateKnowledgeIdle() ) {}
1284 
1287  {
1288  // Move up
1290  {
1291  if (wl->moveUp(playerCharacter))
1292  {
1295  }
1296  else
1297  {
1298  Console("There's no way up here");
1299  }
1300  }
1301  // move down
1302  else
1303  {
1304  if (wl->moveDown(playerCharacter))
1305  {
1308  }
1309  else
1310  {
1311  Console("There's no way down here");
1312  }
1313  }
1314  }
1315  else
1316  {
1317  Console("There's no way up or down here");
1318  }
1319 
1320 
1321  }
1322  _keyboard->keyUp(Keyboard::Q);
1323  _keyboard->keyUp(Keyboard::q);
1324  }
1325 
1326  // Hotbar selection keys
1327  if(_keyboard->isPressed(Keyboard::ONE))
1328  {
1329  selectedHotbar=0;
1330  _keyboard->keyUp(Keyboard::ONE);
1331  }
1332  if(_keyboard->isPressed(Keyboard::TWO))
1333  {
1334  selectedHotbar=1;
1335  _keyboard->keyUp(Keyboard::TWO);
1336  }
1337  if(_keyboard->isPressed(Keyboard::THREE))
1338  {
1339  selectedHotbar=2;
1340  _keyboard->keyUp(Keyboard::THREE);
1341  }
1342  if(_keyboard->isPressed(Keyboard::FOUR))
1343  {
1344  selectedHotbar=3;
1345  _keyboard->keyUp(Keyboard::FOUR);
1346  }
1347  if(_keyboard->isPressed(Keyboard::FIVE))
1348  {
1349  selectedHotbar=4;
1350  _keyboard->keyUp(Keyboard::FIVE);
1351  }
1352  if(_keyboard->isPressed(Keyboard::SIX))
1353  {
1354  selectedHotbar=5;
1355  _keyboard->keyUp(Keyboard::SIX);
1356  }
1357  if(_keyboard->isPressed(Keyboard::SEVEN))
1358  {
1359  selectedHotbar=6;
1360  _keyboard->keyUp(Keyboard::SEVEN);
1361  }
1362  if(_keyboard->isPressed(Keyboard::EIGHT))
1363  {
1364  selectedHotbar=7;
1365  _keyboard->keyUp(Keyboard::EIGHT);
1366  }
1367  if(_keyboard->isPressed(Keyboard::NINE))
1368  {
1369  selectedHotbar=8;
1370  _keyboard->keyUp(Keyboard::NINE);
1371  }
1372  if(_keyboard->isPressed(Keyboard::ZERO))
1373  {
1374  selectedHotbar=9;
1375  _keyboard->keyUp(Keyboard::ZERO);
1376  }
1377 
1378  guiManager.keyboardEvent(_keyboard);
1379  worldViewer.keyboardEvent(_keyboard);
1380  return false;
1381  }
1382 
1383  bool mouseEvent (Mouse* _mouse)
1384  {
1385 
1386  if (playerCharacter==0)
1387  { return false; }
1388 
1389  //int itemClicked = 0; /* 0-99 == Inventory. 100-119 == Ground */
1390  mouseX = _mouse->x;
1391  mouseY = _mouse->y;
1392 
1393  if (craftingMenuActive)
1394  {
1395  menuCrafting.mouseEvent(_mouse);
1396  }
1397 
1398  if (itemSelectionActive)
1399  {
1400  // Right click to cancel out of item selection.
1401  if (subItemSelectionActive==false && _mouse->isRightClick)
1402  {
1403  clearMenus();
1404  }
1405  // Right click to cancel out of interaction selection.
1406  else if (subItemSelectionActive && (_mouse->isRightClick || localTileSelected == 0) )
1407  {
1408  _mouse->isRightClick=false;
1409  _mouse->isLeftClick=false;
1410  clearMenus();
1411  }
1412  else if (subItemSelectionActive)
1413  {
1414  if(interactManager.mouseEvent(_mouse))
1415  {
1416  // Reset the interact menu.
1417  subItemSelectionActive=false;
1418  itemSelectionActive=false;
1419  worldViewer.showHoveredTile = false;
1420  localTileSelected=0;
1421  selectedItemSlot=0;
1422 
1423  // Clear previous overlay tiles.
1424  for ( int i=0;i<vLineOfFire->size();++i)
1425  {
1426  world((*vLineOfFire)(i))->shotOverlay=false;
1427  }
1428  vLineOfFire->deleteAll();
1429  delete vLineOfFire;
1430  vLineOfFire=new Vector <HasXY2 <unsigned long int> * >;
1431  }
1432  }
1433  else if (subItemSelectionActive==false && _mouse->isLeftClick)
1434  {
1435  tileSelectAbsoluteX=worldViewer.hoveredAbsoluteX;
1436  tileSelectAbsoluteY=worldViewer.hoveredAbsoluteY;
1437 
1438  if (world.isSafe(tileSelectAbsoluteX,tileSelectAbsoluteY))
1439  {
1440  if (interactManager.build(useItem, tileSelectAbsoluteX,tileSelectAbsoluteY))
1441  {
1442  localTileSelected=world(tileSelectAbsoluteX,tileSelectAbsoluteY);
1443  subItemSelectionActive=true;
1444  interactManager.clear();
1445 
1446  selectedItemSlot=0;
1447  }
1448  else
1449  {
1450  if ( useItem != 0 )
1451  {
1452  Console("Nothing to use the "+useItem->getName()+" on here.");
1453  }
1454  else
1455  {
1456  Console("Nothing to use here.");
1457  }
1458 
1459  }
1460  }
1461  // Clear previous overlay tiles.
1462  for ( int i=0;i<vLineOfFire->size();++i)
1463  {
1464  world((*vLineOfFire)(i))->shotOverlay=false;
1465  }
1466  vLineOfFire->deleteAll();
1467  delete vLineOfFire;
1468  vLineOfFire=new Vector <HasXY2 <unsigned long int> * >;
1469 
1470  _mouse->isLeftClick=false;
1471  }
1472 
1473 
1474 
1475  }
1476 
1477  // Player can use CTRL+scroll to scroll the hotbar.
1478  // Exit from interaction menu because otherwise I don't feel like doing it the proper way right now.
1479  if(_mouse->isWheelDown && _mouse->ctrlPressed)
1480  {
1481  ++selectedHotbar;
1482  if (selectedHotbar>9) {selectedHotbar=0;}
1483  _mouse->isWheelDown=false;
1484  _mouse->isWheelUp=false;
1485 
1486  // Reset the interact menu.
1487  subItemSelectionActive=false;
1488  itemSelectionActive=false;
1489  worldViewer.showHoveredTile = false;
1490  localTileSelected=0;
1491  selectedItemSlot=0;
1492 
1493  }
1494  if(_mouse->isWheelUp && _mouse->ctrlPressed)
1495  {
1496  --selectedHotbar;
1497  if (selectedHotbar<0) {selectedHotbar=9;}
1498  _mouse->isWheelDown=false;
1499  _mouse->isWheelUp=false;
1500 
1501  // Reset the interact menu.
1502  subItemSelectionActive=false;
1503  itemSelectionActive=false;
1504  worldViewer.showHoveredTile = false;
1505  localTileSelected=0;
1506  selectedItemSlot=0;
1507  }
1508 
1509 
1510 
1511  if (inventoryActive)
1512  {
1513  if (_mouse->isLeftClick)
1514  {
1515  // render inventory slots
1516  int inventoryY = panelY2-250;
1517  int currentFloorItem = 0;
1518 
1519  for (int row = 0;row<12;++row)
1520  {
1521  int currentX = panelX1+250;
1522 
1523  for (int i=0;i<10;++i)
1524  {
1525  if (_mouse->x >= currentX && _mouse->x <= currentX+32
1526  && _mouse->y >=inventoryY-32 && _mouse->y <= inventoryY)
1527  {
1528  clickedItemSlot = row*10 + i;
1529 
1530  if (clickedItemSlot < 100) // INVENTORY GRID
1531  {
1532  if ( carriedItem != 0 ) { carriedItem->owner = playerCharacter; }
1533 
1534  //Swap carried item and inventory grid item.
1535  Item * tempItem = carriedItem;
1536  carriedItem = inventoryGrid[i][row];
1537  if ( carriedItem != 0 ) { carriedItem->owner = playerCharacter; }
1538  inventoryGrid[i][row]=tempItem;
1539  _mouse->isLeftClick=false;
1540  }
1541  else if ( clickedItemSlot-100 >= 0) // PICKING ITEM OFF GROUND
1542  {
1543  if (_mouse->ctrlPressed)
1544  {
1545  if (clickedItemSlot-100 < vItemsOnFloor.size() ) // If player clicked on full ground slot.
1546  {
1547  if ( carriedItem != 0 ) { carriedItem->owner = playerCharacter; }
1548  Item* tempItem = carriedItem;
1549  carriedItem = vItemsOnFloor(clickedItemSlot-100);
1550  if ( carriedItem != 0 ) { carriedItem->owner = playerCharacter; }
1551  vItemsOnFloor.removeSlot(clickedItemSlot-100);
1552  _mouse->isLeftClick=false;
1554  if ( wl != 0 )
1555  {
1556  wl->remove(carriedItem);
1557  // Put down carried item if necessary
1558  if (tempItem != 0)
1559  {
1560  // Put item on map.
1561  wl->put(tempItem,playerCharacter->x,playerCharacter->y);
1562  wl->vItem.push(tempItem);
1563  tempItem->owner = 0;
1564  }
1565  }
1566  }
1567  else // If player clicked on empty ground slot
1568  {
1569  if (carriedItem != 0) // Drop item on ground
1570  {
1572  if ( wl != 0 )
1573  {
1574  // Put item on map.
1575  wl->put(carriedItem,playerCharacter->x,playerCharacter->y);
1576  wl->vItem.push(carriedItem);
1577  vItemsOnFloor.push(carriedItem);
1578  carriedItem->owner = 0;
1579  carriedItem=0;
1580  }
1581  }
1582  }
1583  }
1584  else
1585  {
1586  if (clickedItemSlot-100 < vItemsOnFloor.size() ) // If player clicked on full ground slot.
1587  {
1588  Item* tempItem = carriedItem;
1589  carriedItem = vItemsOnFloor(clickedItemSlot-100);
1590  vItemsOnFloor.removeSlot(clickedItemSlot-100);
1591  _mouse->isLeftClick=false;
1593  if ( wl != 0 )
1594  {
1595  wl->remove(carriedItem);
1596  // Put down carried item if necessary
1597  if (tempItem != 0)
1598  {
1599  // Put item on map.
1600  wl->put(tempItem,playerCharacter->x,playerCharacter->y);
1601  wl->vItem.push(tempItem);
1602  tempItem->owner=0;
1603  }
1604  }
1605  }
1606  else // If player clicked on empty ground slot
1607  {
1608  if (carriedItem != 0) // Drop item on ground
1609  {
1611  if ( wl != 0 )
1612  {
1613  // Put item on map.
1614  wl->put(carriedItem,playerCharacter->x,playerCharacter->y);
1615  wl->vItem.push(carriedItem);
1616  vItemsOnFloor.push(carriedItem);
1617  carriedItem->owner=0;
1618  carriedItem=0;
1619  }
1620  }
1621  }
1622  }
1623  }
1624  }
1625 
1626  // floor inventory
1627  if (row == 10 || row == 11 )
1628  {
1629  ++currentFloorItem;
1630  }
1631 
1632  if ( row==0 )
1633  {
1634  //font8x8.drawText(DataTools::toString(i),currentX,inventoryY,currentX+32,inventoryY-32,true,true);
1635  }
1636  currentX += 34;
1637  }
1638  inventoryY -= 34;
1639  // make a gap for floor inventory
1640  if ( row == 9) {inventoryY -= 5;}
1641  }
1642  //clickedItemSlot = -1;
1643  }
1644  //if (_mouse->isRightClick)
1645  //{carriedItem = 0; clickedItemSlot=-1;
1646  //}
1647  }
1648 
1649  // Default action for selected item. Check to make sure we are clicking somewhere valid.
1650  if (_mouse->isLeftClick && selectedHotbar >= 0 && selectedHotbar < 10 && worldViewer.hoveredAbsoluteX != ABSOLUTE_COORDINATE_NULL && worldViewer.hoveredAbsoluteY != ABSOLUTE_COORDINATE_NULL
1651  && _mouse->x > panelX1+220 )
1652  {
1653 
1654  if (inventoryGrid[selectedHotbar][0] != 0)
1655  {
1656  std::cout<<"DEFAULT USE ITEM: "<<inventoryGrid[selectedHotbar][0]->getName()<<".\n";
1657  }
1658  else
1659  {
1660  std::cout<<"Default hand action\n";
1661  }
1662 
1663  // Clear previous overlay tiles.
1664  for ( int i=0;i<vLineOfFire->size();++i)
1665  {
1666  world((*vLineOfFire)(i))->shotOverlay=false;
1667  }
1668  vLineOfFire->deleteAll();
1669  delete vLineOfFire;
1670  vLineOfFire=new Vector <HasXY2 <unsigned long int> * >;
1671  }
1672 
1673 
1674 
1675  guiManager.mouseEvent(_mouse);
1676 
1677  if (buttonCenterCamera.clicked==true)
1678  {
1679  Console("Centered view");
1681  buttonCenterCamera.unclick();
1682  }
1683 
1684  // Toggle the manual view.
1685  if (buttonManual.clicked==true)
1686  {
1687  std::cout<<"MANUAL\n";
1688  manualActive = !manualActive;
1689  buttonManual.unclick();
1690  }
1691 
1692  // Toggle the character sheet view.
1693  if (buttonCharacterSheet.clicked==true)
1694  {
1695  std::cout<<"CHARACTER SHEET\n";
1696  characterSheetActive = !characterSheetActive;
1697  buttonCharacterSheet.unclick();
1698  }
1699 
1700  // Toggle the crafting menu.
1701  if (buttonCrafting.clicked==true)
1702  {
1703  std::cout<<"CRAFTING\n";
1704  craftingMenuActive = !craftingMenuActive;
1705  menuCrafting.build();
1706  buttonCrafting.unclick();
1707  }
1708 
1709 
1710  // reveal the map
1711  if (buttonRevealMap.clicked==true)
1712  {
1713  std::cout<<"REVEAL MAP\n";
1715  buttonRevealMap.unclick();
1716  }
1717 
1718 
1719  // Toggle the inventory view.
1720  if (buttonInventory.clicked==true)
1721  {
1722  std::cout<<"INVENTORY\n";
1723  inventoryActive = !inventoryActive;
1724 
1725  // build list of items on the floor
1726  if (inventoryActive)
1727  {
1728  vItemsOnFloor.clear();
1730  if ( wl != 0 )
1731  {
1732  for (int i=0;i<wl->vItem.size();++i)
1733  {
1734  if (wl->vItem(i)->x == playerCharacter->x && wl->vItem(i)->y == playerCharacter->y)
1735  {
1736  vItemsOnFloor.push(wl->vItem(i));
1737  }
1738  }
1739  }
1740  }
1741 
1742  buttonInventory.unclick();
1743  }
1744 
1745  // Toggle sneak.
1746  if (buttonSneak.clicked==true)
1747  {
1749 
1750  if ( playerCharacter->isSneaking )
1751  { Console("Entered sneaking mode");
1752  world.updateMaps();
1754  }
1755  else
1756  { Console("Exited sneaking mode");
1757  }
1758  buttonSneak.unclick();
1759  }
1760 
1761 
1762  if (_mouse->isRightClick)
1763  {
1764  std::cout<<"Move here\n";
1765  std::cout<<"Move to: "<<worldViewer.hoveredXTileLocal<<", "<<worldViewer.hoveredYTileLocal<<".\n";
1766  std::cout<<"Move to: "<<worldViewer.hoveredXTile<<", "<<worldViewer.hoveredYTile<<".\n";
1767  _mouse->isRightClick=false;
1768 
1770  {
1771  //path here.
1772  }
1773 
1774  }
1775 
1776  worldViewer.mouseEvent(_mouse);
1777  return false;
1778  }
1779 
1781  {
1782  buttonCenterCamera.setPanel(panelX1,panelY1+304,panelX1+32,panelY1+320);
1783  buttonSneak.setPanel(panelX1+33,panelY1+304,panelX1+65,panelY1+320);
1784  buttonInventory.setPanel(panelX1+66,panelY1+304,panelX1+98,panelY1+320);
1785  buttonManual.setPanel(panelX1+99,panelY1+304,panelX1+131,panelY1+320);
1786  buttonCharacterSheet.setPanel(panelX1+132,panelY1+304,panelX1+164,panelY1+320);
1787  buttonCrafting.setPanel(panelX1+165,panelY1+304,panelX1+197,panelY1+320);
1788  buttonRevealMap.setPanel(panelX1+33,panelY1+287,panelX1+66,panelY1+303);
1789 
1790  worldViewer.setPanel(panelX1,panelY1,panelX2,panelY2);
1791 
1792  interactManager.setPanel(panelX1,panelY1,panelX2,panelY2);
1793  menuCrafting.setPanel(panelX1,panelY1,panelX2,panelY2);
1794 
1795  }
1796 
1797 
1798 };
1799 
1800 #endif
Texture TEX_NPC
Definition: Driver_TextureList.hpp:41
bool mouseEvent(Mouse *_mouse)
Definition: Menu_AdventureMode.hpp:199
bool keyboardEvent(Keyboard *_keyboard)
Definition: Menu_AdventureMode.hpp:962
void Console(std::string s)
Definition: Driver_GlobalObjects.hpp:41
bool mouseEvent(Mouse *_mouse)
Definition: Menu_AdventureMode.hpp:86
void init()
Definition: Menu_AdventureMode.hpp:546
Item * inventoryGrid[10][10]
Definition: Driver_Settings.cpp:106
short int thirst
Definition: Character.hpp:58
Vector< Character * > * getAdjacentCharacters(int, int)
Definition: World_Local.cpp:2612
const int LOCAL_MAP_SIZE
Definition: Driver_Settings.cpp:168
short int health
Definition: Character.hpp:56
unsigned long int hoveredAbsoluteX
Definition: World_Viewer.hpp:181
int worldX
Definition: WorldObject.hpp:34
~Menu_Crafting()
Definition: Menu_AdventureMode.hpp:40
bool moveObject(WorldObject *, int, int)
Definition: World_Local.cpp:1724
World world
Definition: Driver.cpp:43
Item * sourceItem
Definition: Menu_AdventureMode.hpp:148
void setCenterTile(const double _centerTileX, const double _centerTileY, const int _subTileX=LOCAL_MAP_SIZE/2, const int _subTileY=LOCAL_MAP_SIZE/2)
Definition: World_Viewer.hpp:414
void render()
Definition: World_Viewer.hpp:603
Vector< Item * > vItem
Definition: World_Local.hpp:273
const int MAX_THIRST
Definition: Driver_Settings.cpp:178
void render()
Definition: Menu_AdventureMode.hpp:643
void updateKnowledge()
Definition: Character.cpp:694
const std::string ADVENTURE_MODE_MANUAL
Definition: Driver_Settings.cpp:302
WorldViewer worldViewer
Definition: World_Viewer.hpp:1214
Vector< Item * > vItem
Definition: Menu_AdventureMode.hpp:152
int hoveredXTile
Definition: World_Viewer.hpp:179
Texture TEX_PORTRAIT_LING
Definition: Driver_TextureList.hpp:322
InteractManager interactManager
Definition: Menu_AdventureMode.hpp:413
int hoveredXTileLocal
Definition: World_Viewer.hpp:180
Wildcat::Font font8x8
Definition: Driver_GlobalObjects.hpp:49
Character * owner
Definition: Item.hpp:57
Vector< Interaction * > vInteraction
Definition: Menu_AdventureMode.hpp:156
unsigned char skillFishing
Definition: Character.hpp:71
bool isGenerated(unsigned long int _absoluteX, unsigned long int _absoluteY)
Definition: World.cpp:481
Vector< WorldObject * > vObjectGeneric
Definition: LocalTile.hpp:86
Definition: Item.hpp:40
std::string getAll(int)
Definition: LocalTile.cpp:334
bool updateKnowledgeIdle()
Definition: Character.cpp:764
void incrementTicksBacklog(long long unsigned int)
Definition: World.cpp:928
unsigned long int y
Definition: Menu_AdventureMode.hpp:145
Definition: World_Local.hpp:58
unsigned long int hoveredAbsoluteY
Definition: World_Viewer.hpp:181
Vector< std::string > vConsoleMessage
Definition: Driver_GlobalObjects.hpp:34
Vector< Creature * > vCreature
Definition: LocalTile.hpp:92
bool isUnderground
Definition: WorldObject.hpp:24
void revealMap(unsigned int _range)
Definition: Character.cpp:643
Definition: Driver_Settings.cpp:111
Character * playerCharacter
Definition: Driver_Settings.cpp:105
virtual std::string getName()
Definition: Item.cpp:33
#define ABSOLUTE_COORDINATE_NULL
Definition: Driver_Settings.cpp:218
Texture TEX_PORTRAIT_SNEK
Definition: Driver_TextureList.hpp:319
virtual Vector< std::string > * getInteractNames(WorldObject *) override
Definition: Item_All.cpp:14
Menu_Crafting()
Definition: Menu_AdventureMode.hpp:34
short int y
Definition: WorldObject.hpp:22
enumMenu activeMenu
Definition: Driver_Settings.cpp:113
int worldY
Definition: WorldObject.hpp:34
bool showHoveredTile
Definition: World_Viewer.hpp:182
long unsigned int fullY
Definition: WorldObject.hpp:28
void build()
Definition: Menu_AdventureMode.hpp:44
bool remove(WorldObject *)
Definition: World_Local.cpp:2185
Vector< Item * > vItem
Definition: LocalTile.hpp:88
Menu_AdventureMode()
Definition: Menu_AdventureMode.hpp:508
short int hunger
Definition: Character.hpp:57
void setPanel(const int _x1, const int _y1, const int _x2, const int _y2)
Definition: World_Viewer.hpp:398
bool isSneaking
Definition: Character.hpp:89
void eventResize()
Definition: Menu_AdventureMode.hpp:1780
bool mouseEvent(Mouse *_mouse)
Definition: Menu_AdventureMode.hpp:1383
InteractManager()
Definition: Menu_AdventureMode.hpp:160
Vector< Recipe * > * getValidRecipes()
Definition: Recipe.hpp:335
void makeRecipe(Character *_character, int _index)
Definition: Recipe.hpp:361
void clear()
Definition: Menu_AdventureMode.hpp:171
Definition: Character.hpp:29
Definition: Menu_AdventureMode.hpp:25
Vector< WorldObject * > vGeneric
Definition: Menu_AdventureMode.hpp:151
Definition: Menu_AdventureMode.hpp:415
virtual void addToRecipeManager()
Definition: Item.cpp:38
bool isSafe(int _x, int _y)
Definition: World.cpp:470
LocalTile * localSelected
Definition: Menu_AdventureMode.hpp:146
short int x
Definition: WorldObject.hpp:22
Item_Hand itemHand
Definition: Item.hpp:257
bool moveUp(WorldObject *)
Definition: World_Local.cpp:2059
bool mouseEvent(Mouse *mouse)
Definition: World_Viewer.hpp:341
Definition: LocalTile.hpp:34
bool keyboardEvent(Keyboard *_keyboard)
Definition: Menu_AdventureMode.hpp:180
bool build(Item *_sourceItem, unsigned long int _x, unsigned long int _y)
Definition: Menu_AdventureMode.hpp:266
bool moveDown(WorldObject *)
Definition: World_Local.cpp:2024
Vector< Creature * > vCreature
Definition: Menu_AdventureMode.hpp:154
const int MAX_VIEW_RANGE
Definition: Driver_Settings.cpp:174
virtual Vector< std::string > * getInteractNames(WorldObject *_w)
Definition: Item.hpp:174
Vector< Character * > vCharacter
Definition: Menu_AdventureMode.hpp:153
Definition: Menu_AdventureMode.hpp:122
void render()
Definition: Menu_AdventureMode.hpp:398
void render()
Definition: Menu_AdventureMode.hpp:71
void clearMenus()
Definition: Menu_AdventureMode.hpp:515
Texture TEX_GUI_CENTER_CAMERA
Definition: Driver_TextureList.hpp:38
int hoveredYTile
Definition: World_Viewer.hpp:179
bool RENDER_NEXT_FRAME
Definition: Driver_Settings.cpp:211
std::string getFullName() const
Definition: Character.cpp:186
bool keyboardEvent(Keyboard *_keyboard)
Definition: World_Viewer.hpp:261
int hoveredYTileLocal
Definition: World_Viewer.hpp:180
bool put(WorldObject *, int, int, bool subterranean=false)
Definition: World_Local.cpp:1561
void logicTick()
Definition: Menu_AdventureMode.hpp:957
bool shotOverlay
Definition: LocalTile.hpp:79
void updateMaps()
Definition: World.cpp:1050
RecipeManager recipeManager
Definition: Recipe.hpp:395
bool subterraneanMode
Definition: World_Viewer.hpp:188
void rayTrace(unsigned long int _x1, unsigned long int _y1, unsigned long int _x2, unsigned long int _y2, Vector< HasXY2< unsigned long int > *> *vVisibleTiles, bool subterranean=false)
Definition: World.cpp:615
short int maxHealth
Definition: Character.hpp:55
virtual Texture * currentTexture()
Definition: Item.cpp:36
long unsigned int fullX
Definition: WorldObject.hpp:28
bool isAlive
Definition: Character.hpp:48
virtual void interact(WorldObject *obj, int interactionType=0)
Definition: Item.hpp:138
Vector< Character * > vCharacter
Definition: LocalTile.hpp:90
Calendar calendar
Definition: World.hpp:131
const int MAX_HUNGER
Definition: Driver_Settings.cpp:177