HeroEngine Forums

HeroEngine Developers => Developer Created Tutorials => Topic started by: Thazager on Feb 11, 13, 02:56:09 AM

Title: Mini map & World map in window
Post by: Thazager on Feb 11, 13, 02:56:09 AM
Intermediate level scripting
This tutorial puts the minimap and an area map in the same window, and can hide both. It will not work in game layer. It can not use window Docker at present.

In the DOM, create a new (clientside) class.
name = TMP_Map
archtype = guicontrol
add a parent to the class, _minimap

click open script

In new script TMP_MapClassMethods
are methods for interacting with the GUI that we will build
check for mouse clicking on a button
using mouse wheel to zoom in on minimap

Code: [Select]

shared function start()
  win as NodeRef of Class TMP_Map = FindGUIControlByName(None, "minimap")
  if win != None
    destroynode(win)
  .
  win = CreateNodeFromPrototype("TMP_Map")
  win.build = true
  win.name = "minimap"
  win.position.x = 700
  win.position.y = 400

  // Glom the class
  GlomClass("GUIMovePanel", win)

  map as NodeRef of Class GUIPanel = FindGUIControlByName(win, "map")   // clear circle
  map.alphamask.size.x = 0
  map.alphamask.size.y = 0
  map.alphamask.material = ""
  map.visible = false

  player as NodeRef of Class GUIPanel = findGUIControlByName(win, "player")   // make green
  player.defaultStatePresentation.color.r = 0
  player.defaultStatePresentation.color.g = 1
  player.defaultStatePresentation.color.b = 0

  frame as NodeRef of Class GUIPanel = FindGUIControlByName(win, "frame")   // turn off
  frame.texture = ""
  frame.defaultStatePresentation.color.a = 0
.

// Handy mousewheel zooming for the minimap.
method onMouseWheel(args references Class GUIMouseEvent)
  var wheel = args.wheelDelta / 120
  var zoom = GetMiniMapZoom() + (wheel * -4)
  if zoom > 40
    zoom = 40
  .
  SetMiniMapZoom(zoom)
  args.handled = true
.

method onMouseClick(args references Class GUIMouseEvent)
  main as NodeRef of Class _minimap = FindGUIControlByName(None, "minimap")
  Map as NodeRef of Class GUIControl = FindGUIControlByName(main, "map")
  player as NodeRef of Class GUIControl = FindGUIControlByName(main, "player")
  actor as NodeRef of Class GUIControl = findGUIControlByName(main, "actors")

  target as NodeRef of Class GUIControl = args.source
  if args.leftButton
    when target.name
      is "areaButton"
        if player.visible = false
          main.size.y = 290
          actor.visible = true
          player.visible = true
          Map.visible = true
          Map.texture = "MINIMAP"
          Map.defaultStatePresentation.size.x = 256
          Map.defaultStatePresentation.size.y = 256
          Map.defaultStatePresentation.position.x = 128
          Map.defaultStatePresentation.position.y = 128
          EnableMiniMap(true)
        .
      .
      is "worldButton"
        main.size.y = 290
        actor.visible = false
        player.visible = false
        Map.visible = true
        Map.texture = "\GUI\TitanCityGameMap.dds"
        Map.defaultStatePresentation.size.x = 1024
        Map.defaultStatePresentation.size.y = 1024
        Map.defaultStatePresentation.position.x = 0
        Map.defaultStatePresentation.position.y = 0
        EnableMiniMap(false)
      .
      is "exitButton"
        main.size.y = 25
        actor.visible = false
        player.visible = false
        Map.visible = false
        EnableMiniMap(false)
      .
    .
  .
.

// completely overrides behavior of a minimap render call
method _onRenderMiniMap()
  main as NodeRef of Class _minimap = FindGUIControlByName(None, "minimap")
  map as NodeRef of Class GUIControl = FindGUIControlByName(main, "map")
  player as NodeRef of Class GUIControl = FindGUIControlByName(main, "player")
  storage as NodeRef of Class GUIControl = FindGUIControlByName(main, "storage")

//  println("using my OnRenderMiniMap")
//  var map = me._getMinimapTexturePanel()
  if map == None
    return
  .
  var person = GetPlayerCharacterNode()
  if person == None
    return
  .

  position as Vector3 = person["Position"]
  answer as Vector3
  mycenter as Vector3
 
  // WorldSpaceToMiniMapSpace() converts a 3D worldspace position to 2D coordinates within the
  // 512x512 minimap texture.  Here, we're using it to decide how to set the UV coordinates to
  // display the area around the character.  You can also use it to figure out where to place
  // markers for other characters, creatures, etc.

  inRange as Boolean = WorldSpaceToMiniMapSpace(position,answer)
  mycenter = answer
  map.defaultStatePresentation.position.x = answer.x - (map.size.x/2)
  map.defaultStatePresentation.position.y = answer.y - (map.size.y/2)

  var cam = GetActiveCamera()
  if (cam["CameraName"]=="GAME")
    position = cam["Rotation"]
    player.rotation = position.y    // rotate player or map, but not both
//    map.rotation = -position.y
  .
//  frame as NodeRef of Class GUIPanel = me._getMinimapCompassFrame()
//  frame.rotation = map.rotation

  actorCheck as LookupList indexed by String of Boolean
  actorPanel as NodeRef of Class GUIControl = findGUIControlByName(map.parent, "actors")
//  var storage = me._getMinimapActorStorage()
  var actors = GetMinimapCharacters()
  foreach actor in actorPanel.children
    add back actor to storage.children
  .

  var playerColor = me._getMinimapPlayerColor()
  var NPCColor = me._getMinimapNPCColor()
  var HostileColor = me._getMinimapHostileColor()
 
  foreach actor in actors
    dot as NodeRef of Class GUIControl = findGUIControlByName(actorPanel, actor)
    if dot == None
      if storage.children.length > 0
        dot = storage.children[1]
      else
        dot = me._newMinimapActor()
      .
      add back dot to actorPanel.children
      dot.name = actor
      hostile as Boolean = false       
      if hostile == true
        dot.defaultStatePresentation.color = HostileColor
      else if findString(toLower(getcharacterspecification(actor)), "male") > 0
        dot.defaultStatePresentation.color = playerColor
      else
        dot.defaultStatePresentation.color = NPCColor
      .
    .
    position = actor["Position"]
    inRange = WorldSpaceToMiniMapSpace(position,answer)
    if inRange
      answer.x = answer.x - mycenter.x
      answer.y = answer.y - mycenter.y
      answer.z = 0
      var dist = VectorLength(answer)
      if (dist > map.size.x/2)
        dot.visible = false // outside circular distance though within minimap range
      else
        var correctedPos = RotateAndScaleDot(answer,map.rotation,map.scale)
        dot.position.x = correctedPos.x + (map.size.x/2) - (dot.size.x/2)
        dot.position.y = correctedPos.y + (map.size.y/2) - (dot.size.y/2)
        if dot.visible == false
          dot.visible = true
        .
      .
    else
      add back dot to storage.children
    .
  .
  me.lastMinimapUpdate = SYSTEM.TIME.NOW
.

function RotateAndScaleDot(posIn copies Vector3, rot as Float, scale as Float) as Vector3
  posIn.x = posIn.x
  posIn.y = posIn.y
  p as Vector3
  r as Vector3
  r.z = rot
  s as Vector3
  s.x = scale
  s.y = scale
  s.z = scale
  var ret = TransformVector(posIn,p,r,s)
  ret.x = ret.x
  ret.y = ret.y
  return ret
.


In the GUI editor create a new GUI
name = TMP_Map
inherited from = _minimap
class = TMP_Map

In the properties section of TMP_Map
set pos = 300, 200
set size 256, 290                  // currently closed window

add 3 _button, 1 _movepanel

-----------------------------------------------------------------------------------------------------------------------------
select map panel          these were created from the inherit _minimap
set texture to     \GUI\e3_map.dds               // map from clean engine
set pos to 0, 30

select actors
set pos to 0, 30

select player
set autocenter.vertical to false
set pos to 122, 153.5

select frame panel     this is where can add a top border picture to its texture
set pos to 0, 30
set defaultStatePresentation  color to 1,1,1,0             currently unseen

-----------------------------------------------------------------------------------------------------------------------------
Set name of _movepanel to panel
set size to 256, 25
set dockmode to TOP

Set name of 1st button to worldButton
set size to 70, 26
in the button is a text, select it
set text to World

Set name of 2nd button to areaButton
set size to 70, 26
set pos to 70, 0
in the button is a text, select it
set text to Area

Set name of 3rd button to exitButton
set size to 70, 26
set pos to 140, 0
in the button is a text, select it
set text to Close

In (client side) script E_PlayerAccountClassMethods under the chatwindow

Code: [Select]
           TMP_MapClassMethods:start()          // call script to make GUI and needed changes

Title: Re: Mini map & World map in window
Post by: brainache on Feb 11, 13, 09:44:34 AM
Groovy - thanks for posting this
Title: Re: Mini map & World map in window
Post by: nocake on Mar 05, 13, 03:58:15 PM
love the tutorial so far but I have a few questions:

A quick review reveals the code your provided doesnt compile correctly.

88 18 Method HaV_newMinimapActor
Code: [Select]
        dot = me.HaV_newMinimapActor()

122 16 class not found in database
Quote
tmp as Class HaV_miniMap


I have completed your tutorial but found it to not be working.

the command
Code: [Select]
  $GUI._newMinimap() 
returns
Code: [Select]
  13:53:48: $GUI._newMinimap()
13:53:48: SYSTEM:System:{NONE} ERROR 0 : "Parser Error: unknown command" 



Thanks for the tutorial! I hope to improve on this tutorial in the future.
Title: Re: Mini map & World map in window
Post by: nocake on Mar 05, 13, 04:32:59 PM
In your code you have
Code: [Select]
  main as NodeRef of Class TMP_Map = FindGUIControlByName(None, "game.TMP_Map")
which doesnt work for me but this does:

Code: [Select]
  main as NodeRef of Class TMP_Map = FindGUIControlByName(None, "TMP_Map")

I would also suggest setting the button positions in ascending order:

Button 1 (world button)
position:0,0

Button 2 (area button)
position:70,0

Button 3 (close)
position: 140,0

This way the buttons will be properly spaced.




Amazing tutorial just needs some polishing!

Title: Re: Mini map & World map in window
Post by: Thazager on Mar 05, 13, 08:21:11 PM
Thanks, I fixed the errors.
On this tutorial I converted the code we had, where I should have recreated it instead. It had some of the old HaV_ in some places.
Title: Re: Mini map & World map in window
Post by: GameMMO on Mar 26, 13, 01:04:34 PM
why my map is not centered?

Thank You!!   ;D
Title: Re: Mini map & World map in window
Post by: Thazager on Mar 26, 13, 08:06:58 PM
Look through this method HE_onRenderMiniMap(). Near the top is code for setting the location of your camera viewport.

// WorldSpaceToMiniMapSpace() converts a 3D worldspace position to 2D coordinates within the
  // 512x512 minimap texture.  Here, we're using it to decide how to set the UV coordinates to
  // display the area around the character.  You can also use it to figure out where to place
  // markers for other characters, creatures, etc.

  inRange as Boolean = WorldSpaceToMiniMapSpace(position,answer)
  mycenter = answer
  map.defaultStatePresentation.position.x = answer.x - (map.size.x/2)  <-- these 2 lines set the offsets for x and y
  map.defaultStatePresentation.position.y = answer.y - (map.size.y/2)
Title: Re: Mini map & World map in window
Post by: Thazager on Apr 27, 13, 12:05:34 AM
Updated to reflect fixes.
Title: Re: Mini map & World map in window
Post by: Viper155 on Apr 27, 13, 08:57:15 PM
This will not work

Code: [Select]
TMP_MapsClassMethods:start()          // call script to make GUI and needed changes
It should probably be
Code: [Select]
TMP_MapClassMethods:start()          // call script to make GUI and needed changes
Map, not maps.

Mine is not working though, it seems like its not connecting to the TMP_Map script.  Buttons don't work and map is showing the default image.

(http://www.tysontalk.com/UO2D/HE/mappy.png)
Title: Re: Mini map & World map in window
Post by: Thazager on Apr 27, 13, 11:36:00 PM
"Map, not maps" - Thanks, fixed.

default image looks like it has the world button pushed.
This might be another one that needs the TMP_Button added in to work. If that clears things up, I will add it in.
Title: Re: Mini map & World map in window
Post by: Viper155 on Apr 28, 13, 12:23:43 AM
Okay, I made some progress, working well.

First, I couldn't actually click the buttons because the move panel was on top of them. (Doh!)

WorldButton needs to be changed to worldButton

I think that's it.

Thanks for everything you do in this community!
Title: Re: Mini map & World map in window
Post by: Thazager on Apr 28, 13, 02:37:45 AM
Thanks, updated.
Title: Re: Mini map & World map in window
Post by: H3R013 on May 23, 18, 07:04:29 AM
can someone please make an updated minimap tutorial ?

cos i get this when i try to do this minimap tutorial >>

(https://cdn.discordapp.com/attachments/420078312476639234/448817397349220355/minicrap.jpg)
Title: Re: Mini map & World map in window
Post by: Thazager on May 23, 18, 08:06:28 AM
I can reproduce the error here, if I skip adding in the parent class of   "_minimap".
Try adding that as parent class, then remake GUI part.

Its easy to miss something, I did on a few tutorials myself.
Title: Re: Mini map & World map in window
Post by: H3R013 on May 31, 18, 09:45:24 PM
i tried to start this tutorial over and it cant find the _minimap class to parent to as you can see in this pic >>

How do i fix this ?
Title: Re: Mini map & World map in window
Post by: Thazager on Jun 01, 18, 12:41:45 PM
There are 2 different ways/reasons that a class can be parented to another class.  One way is in the definition of the class, which allows the use of its fields and functions thru inheritance. The other way is in the making of the GUI, which adds/presets the controls of the parent GUI to the new class GUI.
Title: Re: Mini map & World map in window
Post by: H3R013 on Jun 01, 18, 01:56:42 PM
I can reproduce the error here, if I skip adding in the parent class of   "_minimap".
Try adding that as parent class, then remake GUI part.

Its easy to miss something, I did on a few tutorials myself.

i found the _minimap today idk why i couldnt fiind it the other day but anyways i remade it to parent this time and now idk how to make the buttons. without buttons im getting errors in the TMP_MapClassMethods >>
how do i make buttons?
Title: Re: Mini map & World map in window
Post by: Thazager on Jun 02, 18, 12:09:20 PM
Ok, lets try taking another approach to editing/changing a script. Close the Client Scripts window, on the top of the editor Click on HeroScript tab, then on HeroScriptEditor. This is the main editor for all scripts. Not only will it allow you to open other script, but it will let you search for already made scripts.

The 2nd button, shows "Open Existing Script or XML File". Click that button and select client or server. Lets start with clicking Client Script. This opens a window showing all the (client) scripts that are in the editor. In the search area (at bottom) type in  utils.  This will show you all the files that have utils as part of the name for the script. You should see MiscUtils as 1 of the scripts, since 1 of the errors you had said the file already exists.  Double click the name or select it from the list (to high lite it), then click ok (button at bottom).

There are some features which can be useful in the script editor. These are the titles for each category that shows - Name, LastModified, Modified By, Owner. Clicking these will show the sorted list by that category.

     Name is the name of file, it can be show forward or reverse order.

     LastModified lets you know when the script was last changed. If you click it 1 time it will show the last script changed on bottom, and next click will change the order to show you what was last changed in your script list.

     Modified By tells you who changed the script last, if you changed it last it will show your email in the category for that script.

     Owner tells you who created the script. The first script were made by the HE (hero engine) devs.

At the bottom of this window are check boxes which will help you find things.  The Mine box will show you only the ones you made.  The Deleted will show any scripts that were deleted (though nothing is ever totally deleted, just removed from the lists, in case you need to get that script back). The Show Engine will add all the engine script to the list. While you can open and look at these, it is not wise to change any of those, as something might break in doing so.