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