5 items

File information

Last updated

Original upload

Created by

Aeltoth Faen and Partoutatix

Uploaded by

Partoutatix

Virus scan

Safe to use

50 comments

  1. Partoutatix
    Partoutatix
    • member
    • 226 kudos
    Sticky
    Let me know of any bugs.

    TODO:
    - Make boat map pins only become visible after you've visited them instead of just disabling them.
    - Make the big World Map Overworld region icons for the different regions only become visible after you've visited those regions.
  2. Yazker
    Yazker
    • member
    • 0 kudos
    I found your mod by searching for a mod that would make points of interest visible on the map when visiting them or by picking up posters on noticeboards that add points of interest. I haven't installed your mod, but from the description the second possibility hasn't been implemented. It would be awesome if you could add this, even more so if there is some distinction between these points of interest and the ones added when visiting them.

    Sorry if the text seemed strange. I wrote it with the help of an automatic translator.
  3. Benna96
    Benna96
    • member
    • 15 kudos
    Hi, love the mod! Though annoyed with the boat pin situation. So...
    I made boat pins become visible upon visiting ^w^ Feel free to use this for an update to the mod if you wish!

    They become visible when you first visit the boat, or, if you've already visited the boat before, once you get close enough for the interaction prompt to show up.
    Only works when the boat is within a 1m radius of the map pin, to avoid false positives in case there's boats without map pins. Connection between the boat & pin is purely through world position.

    Have not tested with all boats, only a handful.


    • Add boat script to the mod (content\scripts\game\vehicles\boat\boat.ws).
      Inside OnAreaEnter event, add a variable:
          var mapPin : SCommonMapPinInstance;

      And set the map pin under the if( player ) conditional:
            if ( TryGetMapPin( mapPin ) )
            {
              FactsAdd('modTrueExploration'+(string)mapPin.id);
            }

      And add this new function to the class (location doesn't matter, I added mine down at the bottom after GetCanBeDestroyed):
        function TryGetMapPin( out mapPin : SCommonMapPinInstance ) : bool
        {
          var i : int;
          var allPins : array< SCommonMapPinInstance >;
          var pin : SCommonMapPinInstance;
          var boatPins : array< SCommonMapPinInstance >;
          var position : Vector;
          var closestPin : SCommonMapPinInstance;
          var closestPinDistance : float;
         
          allPins = theGame.GetCommonMapManager().GetMapPinInstances(theGame.GetWorld().GetPath());
          for ( i = 0; i < allPins.Size(); i += 1 )
          {
            pin = allPins[ i ];
           
            if ( pin.type == 'Boat' )
            {
              boatPins.PushBack(pin);
            }
          }
         
          position = GetWorldPosition();
          closestPinDistance = -1;
          for ( i = 0; i < boatPins.Size(); i += 1 )
          {
            pin = boatPins[ i ];
           
            if ( closestPinDistance < 0 || VecDistanceSquared2D( pin.position, position ) < closestPinDistance )
            {
              closestPinDistance = VecDistanceSquared2D( pin.position, position );
              closestPin = pin;
            }
          }
         
          closestPinDistance = VecDistance2D(closestPin.position, position);
          if(closestPinDistance < 1.0f)
          {
            mapPin = closestPin;
            return true;
          }
          else
          {
            return false;
          }
        }

      The resulting file should look something like this:
      Spoiler:  
      Show
      /***********************************************************************/
      /**   © 2015 CD PROJEKT S.A. All rights reserved.
      /**   THE WITCHER® is a trademark of CD PROJEKT S. A.
      /**   The Witcher game is based on the prose of Andrzej Sapkowski.
      /***********************************************************************/




      import class W3Boat extends CGameplayEntity
      {
        private autobind boatComp : CBoatComponent = single;
        private autobind mountInteractionComp : CInteractionComponent = "mountExplorationInteraction";
        private autobind mountInteractionCompPassenger : CInteractionComponent = "mountExplorationInteractionPassenger";
       
        private saved var canBeDestroyed : bool;    default canBeDestroyed = true;
        private var needEnableInteractions: bool;   default needEnableInteractions = false;

        event OnStreamOut()
        {
          if(theGame.IsBoatMarkedForDestroy(this))
          {
            AddTimer( 'DelayedDestroyBoat', 0.1f );
          }
        }
        timer function DelayedDestroyBoat( td : float , id : int)
        {
          RemoveTimer( 'DelayedDestroyBoat' );
          Destroy();
        }
       
        event OnAreaEnter( area : CTriggerAreaComponent, activator : CComponent )
        {
          var player : CR4Player;
          var mapPin : SCommonMapPinInstance;//modtrueexploration
       
          player = (CR4Player)activator.GetEntity();
         
          if( player )  
          {
            //modtrueexploration++
            if ( TryGetMapPin( mapPin ) )
            {
              FactsAdd('modTrueExploration'+(string)mapPin.id);
            }
            //modtrueexploration--
           
            if( area.GetName() == "FirstDiscoveryTrigger" )
            {
              area.SetEnabled( false );
            }
            else if( area.GetName() == "OnBoatTrigger" )
            {
              player.SetIsOnBoat( true );
              player.BlockAction( EIAB_RunAndSprint, 'OnBoatTrigger', false, false, true );
              player.BlockAction( EIAB_CallHorse, 'OnBoatTrigger', false, false, true );
             
              if( !HasDrowned() )
              {
                needEnableInteractions = true;
               
                if( mountInteractionComp )
                  mountInteractionComp.SetEnabled( true );
                if( mountInteractionCompPassenger && boatComp.user )  
                  mountInteractionCompPassenger.SetEnabled( true );
              }
            }
          }
        }
       
        event OnAreaExit( area : CTriggerAreaComponent, activator : CComponent )
        {
          var player : CR4Player;
       
          player = (CR4Player)activator.GetEntity();
         
          if( player )  
          {
            if( area.GetName() == "OnBoatTrigger" )
            {
              player.SetIsOnBoat( false );
              player.UnblockAction( EIAB_RunAndSprint, 'OnBoatTrigger' );
              player.UnblockAction( EIAB_CallHorse, 'OnBoatTrigger' );
              player.SetBehaviorVariable( 'bRainStormIdleAnim', 0.0 );
             
              needEnableInteractions = false;
             
              if( mountInteractionComp )
                mountInteractionComp.SetEnabled( false );
              if( mountInteractionCompPassenger )
                mountInteractionCompPassenger.SetEnabled( false );
            }
          }
        }
       
        event OnInteractionActivationTest( interactionComponentName : string, activator : CEntity )
        {
          if( ( interactionComponentName == "mountExplorationInteraction" || interactionComponentName == "mountExplorationInteractionPassenger" ) && activator == thePlayer && !HasDrowned() )
          {
            if( !thePlayer.IsActionAllowed( EIAB_MountVehicle ) )
              return false;
             
            return true;
          }
        }
       
        event OnInteractionAttached( interaction : CInteractionComponent )
        {
          interaction.SetEnabled( needEnableInteractions );
        }
       
        timer function DrowningDismount( dt : float, id : int )
        {
          if( !boatComp )
          {
            LogBoatFatal( "Entity doesn't have boat component." );
            return;
          }
         
          boatComp.IssueCommandToDismount( DT_normal );
        }
       
        import final function HasDrowned() : bool;
        import final function SetHasDrowned( val : bool );
       
        event OnStreamIn()
        {
        }
       
        import final function SetTeleportedFromOtherHUB( val : bool );
       
       
       
       
        public function ToggleInteraction( enable : bool )
        {
          var components: array< CComponent >;
          var i : int;
          var inter : CInteractionComponent;
          components = GetComponentsByClassName( 'CInteractionComponent' );
         
          for( i=0; i<components.Size(); i+=1 )
          {
            inter = (CInteractionComponent)components[i];
           
            if( inter )
            {
              inter.SetEnabled( enable );
            }
          }
        }
       
        public function GetBoatComponent() : CBoatComponent
        {
          return boatComp;
        }
       
        public function GetMountInteractionComponent( optional forPassenger : bool ) : CInteractionComponent
        {
          if( forPassenger )    
            return mountInteractionCompPassenger;
          else
            return mountInteractionComp;
        }
       
        public function SetCanBeDestroyed( val : bool ) { canBeDestroyed = val; }
        public function GetCanBeDestroyed() : bool    { return canBeDestroyed; }

        //modtrueexploration++
        function TryGetMapPin( out mapPin : SCommonMapPinInstance ) : bool
        {
          var i : int;
          var allPins : array< SCommonMapPinInstance >;
          var pin : SCommonMapPinInstance;
          var boatPins : array< SCommonMapPinInstance >;
          var position : Vector;
          var closestPin : SCommonMapPinInstance;
          var closestPinDistance : float;
         
          allPins = theGame.GetCommonMapManager().GetMapPinInstances(theGame.GetWorld().GetPath());
          for ( i = 0; i < allPins.Size(); i += 1 )
          {
            pin = allPins[ i ];
           
            if ( pin.type == 'Boat' )
            {
              boatPins.PushBack(pin);
            }
          }
         
          position = GetWorldPosition();
          closestPinDistance = -1;
          for ( i = 0; i < boatPins.Size(); i += 1 )
          {
            pin = boatPins[ i ];
           
            if ( closestPinDistance < 0 || VecDistanceSquared2D( pin.position, position ) < closestPinDistance )
            {
              closestPinDistance = VecDistanceSquared2D( pin.position, position );
              closestPin = pin;
            }
          }
         
          closestPinDistance = VecDistance2D(closestPin.position, position);
          if(closestPinDistance < 1.0f)
          {
            mapPin = closestPin;
            return true;
          }
          else
          {
            return false;
          }
        }
        //modtrueexploration--
       
       
      }

    • In content/script/local/TrueExploration.ws, add an if check for boat pins inside ModTrueExplorationPinShouldBeVisible:
        else if(pin.type == 'Boat')
        {
          return FactsDoesExist('modTrueExploration'+(string)pin.id);
        }
      The resulting file should look like this:
      Spoiler:  
      Show
      /**
      * Given a mappin returns false if it corresponds a noticeboard you haven't visited yet,
      * , an unvisited point of interest (POI)/question mark icon, a usable boat, a player stash. Otherwise returns true.
      * If the map pin belongs to a noticeboard its map icon is changed to the basic white/questless version.
      *
      * @param pin the map pin to be tested and updated.
      * @return false if the map pin shouldn't be displayed on the map, true otherwise.
      */
      function ModTrueExplorationPinShouldBeVisible(out pin : SCommonMapPinInstance): bool
      {
        var board : W3NoticeBoard;
       

        if(pin.type !='NoticeBoard'
          && pin.type !='Boat'
          && pin.type!='PlayerStash'
          && pin.visibleType!='NotDiscoveredPOI'
          )
        {
          return true;
        }

        if(pin.type == 'NoticeBoard')
        {
          board = (W3NoticeBoard)theGame.GetEntityByTag( pin.tag );
         
          if(board)
          {
            //if you want noticeboards to only appear white/questless just remove the "//" double slashes from the line below.
            //pin.visibleType = 'NoticeBoard';
            return board.WasVisited();
          }
        }
        else if(pin.type == 'PlayerStash')
        {
          return FactsDoesExist('modTrueExploration'+NameToString(pin.tag));
        }
        else if(pin.type == 'Boat')
        {
          return FactsDoesExist('modTrueExploration'+(string)pin.id);
        }
        return false;
      }

    1. Partoutatix
      Partoutatix
      • member
      • 226 kudos
      Sounds great! I'll look into adding it soon - hoping a new patch pops out with Sirens of the Deep.
    2. abilitydraft
      abilitydraft
      • member
      • 7 kudos
      Benna, how do you know this stuff...? This is not an ordinary knowledge.
    3. Benna96
      Benna96
      • member
      • 15 kudos
      Knew nothing going in other than general coding things. Looked at how the mod does things, how the vanilla game does things, figured things out as I went.

      My process was something like

      • How does the mod do it for other things? Uses this FactsAdd & FactsDoesExist stuff for storage for PlayerStash, I'll use that.
      • It uses entityName & pin.tag to link stash to its pin, is that a thing I can use? *tests* Nope, boat map pins don't seem to have a tag, and nor do boats have an entityName... (or if they did it was the same for all, I don't remember anymore.)
      • Since boat map pins don't have a tag, how do I uniquely identify the boat map pins? *finds that map pins have an id, problem solved*

      • How do vanilla discoverable things do it? Signposts and whatnot? Oh, they inherit from an entirely different class, nope this doesn't work... Boats do have OnAreaEnter just like they do though, maybe I can use that somehow. *adds a notification upon entering the boat's area*
      • Maybe I can match them by coordinates? *adds the boat's coordinates to the notification & map pins' coordinates to their description on the map, checks ingame* Cool, the boat & the map pin have almost the exact same coordinates.
      • Are coordinates global, or per worldspace? *adds coordinates to some other map pins & compares White Orchard and Velen* Per worldspace, middle seems to be 0 0...
      • I need the boat's worldspace, how do I get it? *can't find out, but does find how to get current world which should work fine too*
      • How do I get all the map pins of a worlspace? I'll need to loop through them to figure out a match. *looks around in vanilla code & finds out*
      • How do I make a filtered list in this programming language? *looks around in vanilla code & finds out* Alright now I'll use that to make a list of boat pins in the current world.
      • Can I calculate the distance between 2 vectors easily? (Vectors are what's used for coordinates.) *finds functions in a math class* Cool, I'll use the 2D squared one to find the closest map pin to the boat. (I know from past experience squared is way more performant when it comes to vectors, you don't need exact distance for finding the closest match.)
      • Let's implement this with the FactsAdd & FactsDoesExist stuff... *tests* Nice, it's working!
      • I'm not sure each boat has a map pin. If one doesn't, entering its area would "discover" the map pin of whatever other boat map pin happens to be the closest. Should probably restrict the closest pin to have to be very close so that can't happen... *tests ingame to see how far boat map pins generally are from the boat* These are all less than 1mm away, 1m should be more than enough for outliers that might be a bit further.
    4. Benna96
      Benna96
      • member
      • 15 kudos
      It may look very complicated, but the logic is really quite simple.

      On encountering a boat,

      • Get all boat map pins
      • Find the closest one to the boat
      • Make sure it's within 1m of the boat
      • Mark the map pin as "discovered", following the example of how it's done for player stashes

      Then in the mod's existing code where it checks if a map pin should be visible, add handling for boat pins, again following example of player stashes.
    5. ElementaryLewis
      ElementaryLewis
      • premium
      • 654 kudos
      I expect good mods from you. Welcome to our community.
    6. abilitydraft
      abilitydraft
      • member
      • 7 kudos
      Thank you for this elaborate explanation, Benna (as expected from MakiseKurisu).
  4. Dyvalas
    Dyvalas
    • premium
    • 30 kudos
    Thanks for this mod, it is a small improvement but essential for us "old gamers" who enjoy a more "Morrowind-like" exploration if you like the comparison.

    Hopefully, the bug of never appearing boats could be fixed in a future update, or at least give the option to not disable them entirely (a little immersion-breaking, but a little better than not having them at all even after being discovered. The boat is a "minor" thing on the map and not really a POI that gives you role-playing and exploration value)

    Also, I see that it is marked as not compatible with "Additional Stash Locations", what does this mean in practice? How will they interact?

    Anyway, thank for all of your mods, they are improving the game way more than all the amazing ultra HD graphical stuff ;)
    1. Partoutatix
      Partoutatix
      • member
      • 226 kudos
      The map pins for the additional stashes introduced by that mod simply don't show up on the map, even after "unlocking" or visiting those stashes. I haven't looked into why that is though I suspect they simply didn't follow the same stash entity name-> map pin name rule as vanilla which this mod relies on.
  5. igorbastos08
    igorbastos08
    • member
    • 0 kudos
    I really like this mod, but the armorers aren't appearing on the map. What should I do?
  6. SinghVerm
    SinghVerm
    • supporter
    • 0 kudos
    Please help. I installed this mod to remove visited POIs, but now, even after removing the mod, the POIs don't stay after I revisit them. Even verifying the game files didn't help
    1. ElementaryLewis
      ElementaryLewis
      • premium
      • 654 kudos
      Did you change the map pins after that?
  7. Banjomir777
    Banjomir777
    • premium
    • 90 kudos
    So, I used this mod for a bit, then decided to uninstall it (because I'm a completionist). However, map markers are not reverting to vanilla. They are still hidden! Now what?
    1. ElementaryLewis
      ElementaryLewis
      • premium
      • 654 kudos
      Did you change the setting afterward?
    2. Banjomir777
      Banjomir777
      • premium
      • 90 kudos
      Ignore me, it is my own stupidity. I forgot to change the map filter settings. It is all working.
    3. SinghVerm
      SinghVerm
      • supporter
      • 0 kudos
      Hey can you help,i have same issue
  8. Serenifly
    Serenifly
    • member
    • 0 kudos
    EDIT:
    Mhh, this is weird. At first I thought harbors weren't working at all. I discovered one and it wasn't saved on the map. Then I tried again, and now the major harbors in Skellige and Valen (plus I think the ones I discovered on my own) are showing. But only when I look at the map when at the helm of a boat. And I have to open, close and open the map a second time. So something is definitely screwy. And it isn't really in the spirit of the mod, but fine with me. Certainly a lot better than not being able to fast travel at all.
  9. Serenifly
    Serenifly
    • member
    • 0 kudos
    It would indeed be cool to have the boats on the world map after you've seen or used them. They are visible on the minimap after all
  10. Malistroth
    Malistroth
    • member
    • 16 kudos
    All harbours on Skellige are unlocked even though I've never discovered them.
    Is this intentional?

    Velen is fine.
    1. Partoutatix
      Partoutatix
      • member
      • 226 kudos
      Not intentional. I'll look into it if you're sure you didn't just buy the harbor maps?
    2. Malistroth
      Malistroth
      • member
      • 16 kudos
      Nah, never even heard about such maps.
      Just travelled there doing the main quest, got on a boat and opened a map.
    3. Partoutatix
      Partoutatix
      • member
      • 226 kudos
      These books, and they're not the only ones that add information and map markers for the skellige isles. Are you sure it's really all harbors unlocked and not just a few?

      I just tested it out with someone's save on nexus from right before skellige and I can't reproduce the issue you're having: there were only a handful of already unlocked harbors when I got to skellige (out of 17 total) presumably from information gathered and books read before getting there - certainly not all of them.

      I can look into disabling map pin info gathering from books - but it probably wouldn't be retroactive and wouldn't solve some unrelated issue with all harbors being unlocked.
    4. Malistroth
      Malistroth
      • member
      • 16 kudos
      These books unlock harbors indeed, but the major islands are still get unlocked without any reading, just tested with my first time arriving save file without reading any books about Skellige. Maybe some other books or dialogues unlock them, but I'd rather do that by exploring anyway, otherwise it feels like cheating.
    5. Partoutatix
      Partoutatix
      • member
      • 226 kudos
      Making it so books don't add map markers seems simple enough, just a one line change in vanilla. As for the rest I'll look into it.
    6. Partoutatix
      Partoutatix
      • member
      • 226 kudos
      I think this new mod by Merseyrockoff might fix that: https://www.nexusmods.com/witcher3/mods/9050
  11. delular100
    delular100
    • member
    • 3 kudos
    It would be great if I could keep only the Notice Boards... Is that something I can easily edit myself?
    1. Partoutatix
      Partoutatix
      • member
      • 226 kudos
      Probably. In the local file try replacing 

      return board.WasVisited();

      with 

      return true;
    2. delular100
      delular100
      • member
      • 3 kudos
      Awesome, it worked, thank you!