HeroEngine Forums
Welcome, Guest. Please login or Register for HeroCloud Account.
Pages: [1] 2 3

Author Topic: Porting over the News System from HJRef  (Read 7845 times)

Jrome90

  • General Accounts
  • *
  • Posts: 330
    • View Profile
Porting over the News System from HJRef
« on: Jan 09, 12, 10:21:53 PM »

The first thing I did after getting access to HeroCloud was port over the News system from HJRef. I felt the news system was perfect for communicating with others. As soon as they login, they see the news. And it seemed pretty easy to do.

This isn’t really a tutorial, but I do hope you learn some things in the process. Please do not just copy and paste the scripts. But instead try to understand how everything works while typing it out.

The News System comprises the following:
•   8 client side classes
•   2 server side classes
•   Adding a few lines of code to E_AccountClassMethods (Server)
•   8 GUI Prototypes (copying and pasting only)
*I am aware that anything starting with a “_” is reserved for HE. Some of the following does use the “_”. Because that is how it was done in HJRef, I decided to not change it to make it a little easier to port over. Feel free to name anything however you like. Remember to change anything that needs to be changed*
*This is still untested. I plan to test it. I am 98% sure it will work. If you don’t want to take the time to follow this. Let me know if it is because you are unsure it will work. If it does work please let me know, if it doesn’t please tell me where I went wrong*
Thanks


Although I really do not want to use the “code” formatting. I am going to do it anyways. It will take many posts for just the scripts, if I were to use BBCode to make the text look nice.

GameNewsBrowser Class & other required classes

Creating the class “GameNewsBrowser” part 1

1.   On the client side, create a new class named “GameNewsBrowser”
Description: News Browser GUI
Archetype: guicontrol

¬

2.   Add the Parent Classes
•   _GUIBaseWindow
•   ObsListener
3.   Click Save

Before we can compile and submit the script that will be associated with this class, we need to create another client side class named “_GUIFilterList”. We will do that now

Creating the class “_GUIFilterList” Part 1

1.   On the client side, create a new class named “_GUIFilterList”
Description: Sort through a list
Archetype: guicontrol



2.   Add the Parent Class
•   _GUIGroupBox
3.   Click Save
Before we can compile and submit the script that will be associated with this class, we need to create another client side class named “_GUIFilterRowIndex”.

Creating the class “_GUIFilterRowIndex” Part 1
*By now, you should know how to create a new class. To lessen the amount of images used, I am no longer going to show what the Window “Enter New Class Name” should look like.*


1.   On the client side, create a new class named “_GUIFilterRowIndex”
Description: index for a row
Archetype: data

We are going to need to create a field in the DOM to use for this class. We will do that now

Creating the field “_filterListRowIndexID”

1.   Make sure you are on the Client side
2.   Select “Fields”
3.   Click “New Field” (If it is greyed out, uncheck “read only”)



4.   Create the new field.
Name: _filterListRowIndexID
Description: index for a row
Type: id

Leave everything else at their default settings
5.   Click Ok,
6.   Then save the newly created field

Creating the class “_GUIFilterRowIndex” Part 2
1.   Open up the class “_GUIFilterRowIndex”
2.   Add the field “_filterListRowIndexID” (To do this, do the same thing as if you were adding a parent class. But instead choose “Field” in the drop down.)
3.   Click Save

We are finished with this class. We can now add the required script to our class “_GUIfilterList” and then compile and submit.

Creating the class “_GUIFilterList” Part 2

1.   Click “Open Script”
2.   Click “Make Empty Script”
3.   Type up the following script:


Code: (hsl) [Select]
//#define debug

method onControlBuild()
  me._allowTitlebar(me.allowTitlebar)
.
method _populateIndexedFilterList(headers as List of String, data as LookupList indexed by ID of List of String)
  //---------------------------------------------------------------------
  // There will be one column for each header
  // Each row of data is one list of string in list of list of string
  // If list of strings are longer than they should be, data is truncated
  //---------------------------------------------------------------------
  #if debug
    println("_populateFilterList called by " + SYSTEM.EXEC.CALLEDBYSCRIPT)
  #endif
  var sc = me._getMySortableCollection()
  sc._removeAllCollectionRows()
  sc._setCollectionColumnHeaders(headers)
  listEntry as List of String
  dList as List of String
  foreach i in data
    listEntry = data[i]
    var newRow = sc._addCollectionRow(listEntry)
    GlomClass("_GUIFilterRowIndex", newRow)
    where newRow is kindof _GUIFilterRowIndex
      newRow._filterListRowIndexID = i
    .
  .
  var clientarea = FindGUIControlByName(sc, "clientarea")
  foreach child in clientarea.children
    child.hoverStatePresentation.color.r = 0.75
    child.hoverStatePresentation.color.g = 1.0
    child.hoverStatePresentation.color.b = 0.73
    child.hoverStatePresentation.color.a = 1.0
   
    child.selectedStatePresentation.color.r = 0.60
    child.selectedStatePresentation.color.g = 1.0
    child.selectedStatePresentation.color.b = 0.0
    child.selectedStatePresentation.color.a = 1.0

    child.selectedHoverStatePresentation.color.r = 0.60
    child.selectedHoverStatePresentation.color.g = 1.0
    child.selectedHoverStatePresentation.color.b = 0.0
    child.selectedHoverStatePresentation.color.a = 1.0
  .
.
method _populateFilterList(headers as List of String, data as List of List of String)
  //---------------------------------------------------------------------
  // There will be one column for each header
  // Each row of data is one list of string in list of list of string
  // If list of strings are longer than they should be, data is truncated
  //---------------------------------------------------------------------
  #if debug
    println("_populateFilterList called by " + SYSTEM.EXEC.CALLEDBYSCRIPT)
  #endif
  var sc = me._getMySortableCollection()
  sc._removeAllCollectionRows()
  if sc.columnWidths <> ""
    #if debug
      println("Setting column widths to " + sc.columnWidths)
    #endif
    var header = sc._getSortableCollectionHeader()
    header.columnWidths = sc.columnWidths
  .
  sc._setCollectionColumnHeaders(headers)
  #if debug
    var header = sc._getSortableCollectionHeader()
    println("headers widths: " + header.columnWidths)
  #endif
  sc._setSortableCollectionIsSortable(false)
  listEntry as List of String
  dList as List of String
  loop i from 1 to data.length
    clear listEntry
    dList = data[i]
    loop x from 1 to headers.length
      add back dList[x] to listEntry
    .
    var newRow = sc._addCollectionRow(listEntry)
  .
  sc._setSortableCollectionIsSortable( true )
  sc._sortCollectionRows()

  var clientarea = FindGUIControlByName(sc, "clientarea")
  foreach child in clientarea.children
    child.hoverStatePresentation.color.r = 0.75
    child.hoverStatePresentation.color.g = 1.0
    child.hoverStatePresentation.color.b = 0.73
    child.hoverStatePresentation.color.a = 1.0
   
    child.selectedStatePresentation.color.r = 0.60
    child.selectedStatePresentation.color.g = 1.0
    child.selectedStatePresentation.color.b = 0.0
    child.selectedStatePresentation.color.a = 1.0

    child.selectedHoverStatePresentation.color.r = 0.60
    child.selectedHoverStatePresentation.color.g = 1.0
    child.selectedHoverStatePresentation.color.b = 0.0
    child.selectedHoverStatePresentation.color.a = 1.0
  .
.
method _getMySortableCollection() as NodeRef of Class _GUISortableCollection
  return findGUIControlByName(me, "clientarea.scrollable.clientarea.sortableCollection")
.
function filterText_onKeyDown(args references Class GUIKeyboardEvent)
  // Keydown for the filtertextbox
  //
  control as NodeRef of Class GUIControl = me
  #if debug
    println("filterText_onKeyDown()")
  #endif
  var filterList = control.parent.parent.parent.parent
  var sortableCollection = filterList._getMySortableCollection()
  where me
    is kindof timeDelayedTextInput
      if args.keyCode == "38"
        sortableCollection._selectPreviousCollectionRow()
        args.interrupt = true
        return
      else if args.keyCode == "40"
        sortableCollection._selectNextCollectionRow()
        args.interrupt = true
        return
      else if args.keyCode == "13"   // enter key
        me.textInputTimer.forceTick()
        args.interrupt = true
        return
      else if args.keyCode == "27"   // ESC key
        me.value = ""
        me.textInputTimer.forceTick()
        args.interrupt = true
        return
      .
      if me.textInputTimer.timerState != "OFF"
        me.textInputTimer.stop()
      .
      me.textInputTimer.FireRate = 0:00:00.200
      me.textInputTimer.script = SYSTEM.EXEC.THISSCRIPT
      me.textInputTimer.start()
    .
    default
      ScriptError("missing the timeDelayedTextInput class")
    .
  .
.

function textInputTimer_tick()
  // The text input box has a delay on its processing of filtering the sortablecollection, this is just
  //   an efficiency thing.
  //
  #if debug
    println("textInputTimer_tick()")
  #endif
  control as NodeRef of Class GUIControl = me
  var filterList = control.parent.parent.parent.parent
  var sortableCollection = filterList._getMySortableCollection()
  where me
    is kindof timeDelayedTextInput
      if me.textInputTimer.timerState != "OFF"
        me.textInputTimer.stop()
      .
      sortingColumn as Integer
      if sortableCollection.columnSortOrder.length >= 1
        sortingColumn = sortableCollection.columnSortOrder[1]
      else
        sortingColumn = 1
      .
      var columns = sortableCollection._getCollectionColumnHeaders()
     
      var rows = sortableCollection._getAllCollectionRows()
      foreach row in rows
        // initialize them as not shown
        row.visible = false
      .
     
      loop c from 1 to sortableCollection.columnSortOrder.length
        foreach row in rows
          var contents = row._getCollectionRowContents()
          assert(contents.length == columns.length, "content length not equal to number of columns")
          if filterMatch(me.value, contents[c])
            row.visible = true
          .
        .
      .
    .
    default
      ScriptError("missing the timeDelayedTextInput class")
    .
  .
.
function filterMatch(matchOn as String, compareText as String) as Boolean
// Handles comparisons including NULL and wildcard(*) matching
//
  if matchOn == "" or matchOn == "*"
    return true
  .
  if FindString(ToLower(compareText), ToLower(matchOn)) > 0
    return true
  .
  return false
.
function sortableCollection_OnMouseDblClick(args references Class GUIMouseEvent)
  c as NodeRef of Class GUIControl = me
  d as NodeRef of Class GUIControl = c.parent
  e as NodeRef of Class GUIControl = d.parent
  f as NodeRef of Class GUIControl = e.parent
  filterList as NodeRef of Class GUIControl = f.parent
  handled as Boolean = false
  if filterList <> None
//    if HasMethod(filterList, "HE_SortableCollection_OnMouseDblClick")
//      handled = filterList.HE_SortableCollection_OnMouseDblClick(me, args)
//    .
//    if handled = false
//      if filterList.script <> None
//        if HasFunction(filterList.script, "HE_SortableCollectionOnMouseDblClick")
//          handled = filterList.script:HE_SortableCollectionOnMouseDblClick(me, args)
//        .
//      .
//    .
  .
  args.handled = handled
.

4.   Compile and Submit.

We are now finished with this Class.
« Last Edit: Aug 12, 12, 07:20:41 PM by Jrome90 »
Logged

Jrome90

  • General Accounts
  • *
  • Posts: 330
    • View Profile
Re: Porting over the News System from HJRef (Please Not reply yet)
« Reply #1 on: Jan 09, 12, 10:22:33 PM »

Creating the class “GameNewsBrowser” part 2

1.   Click “Open Script”
2.   Click “Make Empty Script”
3.   Type up the following script:


Code: (hsl) [Select]
#define debug
method onControlBuild()
  $News.addListener(me)
  var q = QueryAssociation($News, "base_hard_association", me)
  if q.length > 0
    RemoveAssociation($News, "base_hard_association", me)
  .
  $News.News_RequestNewsUpdate()
.
method GameNewsBrowser_Populate()
  //--------------------------------------
  // Put all the news items in the browser
  //--------------------------------------
  headerMap as List of String
  add back "ID" to headerMap
  add back "Date" to headerMap
  add back "Category" to headerMap
  add back "Text" to headerMap
  add back "Author" to headermap
 
  row as List of String
  rows as List of List of String

  foreach key in $News.NewsItems
    clear row
    add back $News.NewsItems[key].NewsID to row
    add back $News.NewsItems[key].NewsDate to row
    add back $News.NewsItems[key].NewsCategory to row
    add back $News.NewsItems[key].NewsText to row
    add back $News.NewsItems[key].signature to row
   
    add back row to rows
  .
  var filterList = me.GameNewsBrowser_GetFilterList()
  filterList._populateFilterList(headerMap, rows) 
.
method GameNewsBrowser_UpdateItem(newsID as ID)
  //------------------------------------------
  // Update the specified news item in browser
  //------------------------------------------
  if newsID >= 0
    key as String = newsID
    var filterList = me.GameNewsBrowser_GetFilterList()
    var sc = filterList._getMySortableCollection()
    var rows = sc._getSelectedCollectionRows()
    rowList as List of String
    found as Boolean = false
    foreach row in rows
      rowList = row._getCollectionRowContents()
      if rowList[1] = key
        //----------------------------------
        // This is the one we want to update
        //----------------------------------
        newList as List of String
        add back $News.NewsItems[newsID].NewsID to newList
        add back $News.NewsItems[newsID].NewsDate to newList
        add back $News.NewsItems[newsID].NewsCategory to newList
        add back $News.NewsItems[newsID].NewsText to newList
        add back $News.NewsItems[newsID].signature to newList

        row._setCollectionRowContents(newList)
        found = true
        break
      .
    .
    if found = false
      me.GameNewsBrowser_Populate()
    .
  .
.
method GameNewsBrowser_GetFilterList() as NodeRef of Class _GUIFilterList
  return FindGUIControlByName(me, "scrollable.clientarea._filterList")
.
method EventRaised( obs as NodeRef of Class ObsSubject, data as NodeRef )
  where data is kindof eventObject
    #if debug
      println("EventRaised: " + data.eventType)
    #endif
    when data.eventType
      is "NEWSUPDATE"
        me.GameNewsBrowser_Populate()
      .
      is "NEWSITEMUPDATE"
        me.GameNewsBrowser_UpdateItem(data.eventAffectsID)
      .
    .
  .
.
method destroyListener()
 
.
method _onButtonMouseClick(btn as NodeRef of Class _GUIButton, args references Class GUIMouseEvent)
  when btn.name
    is "AddNewsItemButton"
      item as Class NewsItem
      item.NewsID = 0
      item.NewsDate = SYSTEM.TIME.NOW
      item.NewsCategory = General
      item.NewsText = ""
      item.signature = ""
      me.GameNewsBrowser_LaunchNewsItemEditor(item)
    .
    is "EditNewsItemButton"
      var item = me.GameNewsBrowser_GetSelectedNewsItem()
      if item.NewsID >= 0
        me.GameNewsBrowser_LaunchNewsItemEditor(item)
      .
    .
    is "DeleteNewsItemButton"
      var item = me.GameNewsBrowser_GetSelectedNewsItem()
      if item.NewsID >= 0
        me.GameNewsBrowser_ConfirmDelete()
      .
    .
  .
.
method GameNewsBrowser_ConfirmDelete()
  c as NodeRef of Class GUIControl
  c = CreateNodeFromPrototype("NewsItemConfirmDelete")
  c.build = true
  c.centerControlOver(me)
  c.createModalDialog(me)
  var item = me.GameNewsBrowser_GetSelectedNewsItem()
  lbl as NodeRef of Class GUILabel = FindGUIControlByName(c, "scrollable.clientarea._label")
  str as String
  str = "Confirm Delete News Item:$R"
  str = str + "ID: " + item.NewsID + "$R"
  str = str + "Date: " + item.NewsDate + "$R"
  str = str + "Category: " + item.NewsCategory + "$R"
  str = str + "Text: " + item.NewsText
  str = str + "Signature: " + item.signature
  lbl.text = str
.
function ConfirmDeleteButton_onMouseClick(args references Class GUIMouseEvent)
  //---------------------------------------
  // Delete the selected news item for real
  //---------------------------------------
  var root = args.source.rootParent()
  var browser = root.findMyModalOwner()
  var item = browser.GameNewsBrowser_GetSelectedNewsItem()
  if item.NewsID >= 0
    $News.News_DeleteNewsItem(item)
  .
  destroynode(root)
.
method GameNewsBrowser_GetSelectedNewsItem() as Class NewsItem
  newsID as ID
  var filterList = me.GameNewsBrowser_GetFilterList()
  var sc = filterList._getMySortableCollection()
  var rows = sc._getSelectedCollectionRows()
  rowList as List of String
  foreach row in rows
    if row.selected = true
      rowList = row._getCollectionRowContents()
      newsID = rowList[1]
      break
    .
  .
  item as Class NewsItem = $News.NewsItems[newsID]
 
  return item
.
method GameNewsBrowser_LaunchNewsItemEditor(newsItem as Class NewsItem)
  editor as NodeRef of Class GameNewsEditor = CreateNodeFromPrototype("GameNewsEditor")
  editor.build = true
  editor.centerControlOver(me)
  editor.createModalDialog(me)
  editor.GameNews_Populate(newsItem)
.
method _onSortableCollectionRowMouseDblClick(c as NodeRef of Class GUIControl, args references Class GUIMouseEvent)
  //----------------------------------
  // Edit the double clicked news item
  //----------------------------------
  c.selected = true
  var item = me.GameNewsBrowser_GetSelectedNewsItem()
  if item.NewsID >= 0
    me.GameNewsBrowser_LaunchNewsItemEditor(item)
  .
.
function open()
  c as NodeRef of Class GUIControl = CreateNodeFromPrototype("GameNewsBrowser")
  c.build = true
  c.centerControlOver(None)
.
remote function RemoteOpen()
  open()
.
shared function onCollapsableCategoryItemClick(args references Class GUIMouseEvent)
  open()
  args.handled = true
.

4.   You still will not be able to compile and submit this script. The script requires the classes “News Item”, and “News”. Also it uses the Prototype “News”.
5.   For now, Just click save, it will save the script locally.



Lets Create the GUI Prototypes needed for the Game News Browser. All we need to do is copy and paste the below XML

Creating the XML GUI for the Game News Browser (Copy/Paste)
1.   Create new XML GUI Prototypes for each one below

_FilterList
Code: (xml) [Select]
<createControlType class='_GUIFilterList' type='_filterList' description='for displaying a list of things with a filter box' treePath='CleanEngine\SortableCollection' name="_filterList" dockMode="FILL" inheritHoveringState="false" textureFilter="false">
  <minimumSize x="200" y="150"/>
  <defaultStatePresentation>
    <color r="0" g="0" b="0" a="0"/>
  </defaultStatePresentation>
  <_spacer name="topSpacer" dockMode="TOP">
    <size x="731" y="10"/>
  </_spacer>
  <_panel name="top" dockMode="TOP">
    <defaultStatePresentation>
      <color r="0" g="0" b="0"/>
    </defaultStatePresentation>
  </_panel>
  <_panel name="bottom" dockMode="BOTTOM">
    <defaultStatePresentation>
      <color r="0" g="0" b="0"/>
    </defaultStatePresentation>
  </_panel>
  <_panel name="right" dockMode="RIGHT">
    <defaultStatePresentation>
      <color r="0" g="0" b="0"/>
    </defaultStatePresentation>
  </_panel>
  <_panel name="left" dockMode="LEFT">
    <defaultStatePresentation>
      <color r="0" g="0" b="0"/>
    </defaultStatePresentation>
  </_panel>
  <_spacer name="titleSpacer" dockMode="TOP">
    <size x="729" y="10"/>
    <defaultStatePresentation>
      <color a="1"/>
    </defaultStatePresentation>
  </_spacer>
  <_panel name="titlebar">
    <position x="30" y="2"/>
    <size x="100" y="20"/>
    <defaultStatePresentation>
      <color r="0" g="0.49000001" b="0.74000001"/>
    </defaultStatePresentation>
    <_panel name="top" dockMode="TOP">
      <defaultStatePresentation>
        <color r="0" g="0" b="0"/>
      </defaultStatePresentation>
    </_panel>
    <_panel name="bottom" dockMode="BOTTOM">
      <defaultStatePresentation>
        <color r="0" g="0" b="0"/>
      </defaultStatePresentation>
    </_panel>
    <_panel name="right" dockMode="RIGHT">
      <size x="5" y="18"/>
      <defaultStatePresentation>
        <color r="0" g="0" b="0"/>
      </defaultStatePresentation>
    </_panel>
    <_panel name="left" dockMode="LEFT">
      <defaultStatePresentation>
        <color r="0" g="0" b="0"/>
      </defaultStatePresentation>
    </_panel>
    <_label name="title" dockMode="FILL" textPadding="2" justification="LEFT">
      <defaultStatePresentation>
        <color r="0.899999976" g="0.899999976" b="0.899999976"/>
      </defaultStatePresentation>
    </_label>
  </_panel>
  <_spacer name="clientarea" dockMode="FILL">
    <defaultStatePresentation>
      <color a="1"/>
    </defaultStatePresentation>
    <_spacer name="tspacer" dockMode="TOP">
      <size x="729" y="5"/>
      <defaultStatePresentation>
        <color r="0" g="0" b="0"/>
      </defaultStatePresentation>
    </_spacer>
    <_spacer name="bspacer" dockMode="BOTTOM">
      <size x="729" y="5"/>
      <defaultStatePresentation>
        <color r="0" g="0" b="0"/>
      </defaultStatePresentation>
    </_spacer>
    <_spacer name="lspacer" dockMode="LEFT">
      <size x="5" y="629"/>
      <defaultStatePresentation>
        <color r="0" g="0" b="0"/>
      </defaultStatePresentation>
    </_spacer>
    <_spacer name="rspacer" dockMode="RIGHT">
      <size x="5" y="629"/>
      <defaultStatePresentation>
        <color r="0" g="0" b="0"/>
      </defaultStatePresentation>
    </_spacer>
    <_panel name="filterPanel" dockMode="BOTTOM">
      <size x="719" y="32"/>
      <anchor right="true"/>
      <defaultStatePresentation>
        <color r="0" g="0" b="0" a="0"/>
      </defaultStatePresentation>
      <_spacer name="tspacer" dockMode="TOP">
        <size x="719" y="5"/>
        <defaultStatePresentation>
          <color r="0" g="0" b="0"/>
        </defaultStatePresentation>
      </_spacer>
      <_spacer name="bspacer" dockMode="BOTTOM">
        <size x="719" y="5"/>
        <defaultStatePresentation>
          <color r="0" g="0" b="0"/>
        </defaultStatePresentation>
      </_spacer>
      <_panel name="filterTextBorder" dockMode="FILL">
        <anchor top="false" bottom="true" right="true"/>
        <defaultStatePresentation>
          <color r="0.5" g="0.5" b="0.5"/>
        </defaultStatePresentation>
        <_spacer name="tspacer" dockMode="TOP">
          <defaultStatePresentation>
            <color r="0" g="0" b="0"/>
          </defaultStatePresentation>
        </_spacer>
        <_spacer name="bspacer" dockMode="BOTTOM">
          <defaultStatePresentation>
            <color r="0" g="0" b="0"/>
          </defaultStatePresentation>
        </_spacer>
        <_spacer name="rspacer" dockMode="RIGHT">
          <defaultStatePresentation>
            <color r="0" g="0" b="0"/>
          </defaultStatePresentation>
        </_spacer>
        <_spacer name="lspacer" dockMode="LEFT">
          <defaultStatePresentation>
            <color r="0" g="0" b="0"/>
          </defaultStatePresentation>
        </_spacer>
        <_textInputBox name="filterText" dockMode="FILL" script="_GUIFilterListClassMethods" textDefaultColor="#0,0,0,1.0" glomClass="timeDelayedTextInput">
          <defaultStatePresentation>
            <color r="0.899999976" g="0.899999976" b="0.899999976"/>
          </defaultStatePresentation>
          <selectedStatePresentation>
            <color r="0.123000003" g="0.897000015" b="0.324000001"/>
          </selectedStatePresentation>
        </_textInputBox>
      </_panel>
    </_panel>
    <_scrollableParent name="scrollable">
      <anchor bottom="true" right="true"/>
      <set name="_filterList.clientarea.scrollable.clientarea">
        <_spacer name="tspacer" dockMode="TOP">
          <size x="719" y="2"/>
          <anchor right="true"/>
          <defaultStatePresentation>
            <color r="0" g="0.49000001" b="0.74000001" a="1"/>
          </defaultStatePresentation>
        </_spacer>
      </set>
      <set name="_filterList.clientarea.scrollable.clientarea">
        <_spacer name="bspacer" dockMode="BOTTOM">
          <size x="719" y="2"/>
          <anchor right="true"/>
          <defaultStatePresentation>
            <color r="0" g="0.49000001" b="0.74000001" a="1"/>
          </defaultStatePresentation>
        </_spacer>
      </set>
      <set name="_filterList.clientarea.scrollable.clientarea">
        <_spacer name="lspacer" dockMode="LEFT">
          <size x="2" y="593"/>
          <anchor bottom="true"/>
          <defaultStatePresentation>
            <color r="0" g="0.49000001" b="0.74000001" a="1"/>
          </defaultStatePresentation>
        </_spacer>
      </set>
      <set name="_filterList.clientarea.scrollable.clientarea">
        <_spacer name="rspacer" dockMode="RIGHT">
          <size x="2" y="593"/>
          <anchor bottom="true"/>
          <defaultStatePresentation>
            <color r="0" g="0.49000001" b="0.74000001" a="1"/>
          </defaultStatePresentation>
        </_spacer>
      </set>
      <set name="_filterList.clientarea.scrollable.clientarea">
        <_sortableCollection name="sortableCollection" script="_GUIFilterListClassMethods">
          <rowColor2 r="0.800000012" g="0.800000012" b="0.800000012"/>
          <set name='_filterList.clientarea.scrollable.clientarea.sortableCollection.scrollbar' attribute='visible' value="false"/>
        </_sortableCollection>
      </set>
    </_scrollableParent>
  </_spacer>
</createControlType>


GameNewsBrowser
Code: (xml) [Select]
<createControlType inheritFrom='_window' class='GameNewsBrowser' type='GameNewsBrowser' description='' treePath='CleanEngine' name="GameNewsBrowser">
  <size x="950" y="495"/>
  <set name='GameNewsBrowser.titlebar.title' attribute='text' value=" Game News Editor"/>
  <set name="GameNewsBrowser.scrollable.clientarea">
    <_panel name="buttonpanel" dockMode="BOTTOM">
      <size x="927" y="44"/>
      <_horizontalRule name="_horizontalRule" dockMode="TOP"/>
      <_button name="AddNewsItemButton">
        <position x="10" y="9"/>
        <autoCenter vertical="true"/>
        <set name='GameNewsBrowser.scrollable.clientarea.buttonpanel.AddNewsItemButton.text' attribute='text' value="Add"/>
      </_button>
      <_button name="EditNewsItemButton">
        <autoCenter horizontal="true" vertical="true"/>
        <set name='GameNewsBrowser.scrollable.clientarea.buttonpanel.EditNewsItemButton.text' attribute='text' value="Edit"/>
      </_button>
      <_button name="DeleteNewsItemButton">
        <position x="854" y="9"/>
        <anchor top="false" bottom="true" left="false" right="true"/>
        <autoCenter vertical="true"/>
        <set name='GameNewsBrowser.scrollable.clientarea.buttonpanel.DeleteNewsItemButton.text' attribute='text' value="Delete"/>
      </_button>
    </_panel>
  </set>
  <set name="GameNewsBrowser.scrollable.clientarea">
    <_filterList name="_filterList">
      <set name='GameNewsBrowser.scrollable.clientarea._filterList.clientarea.scrollable.clientarea.sortableCollection' attribute='columnWidths' value="50,120,150"/>
    </_filterList>
  </set>
</createControlType>
Remember, The Game News Browser still won’t work.
« Last Edit: Aug 12, 12, 07:27:25 PM by Jrome90 »
Logged

Jrome90

  • General Accounts
  • *
  • Posts: 330
    • View Profile
Re: Porting over the News System from HJRef (Please Not reply yet)
« Reply #2 on: Jan 09, 12, 10:23:05 PM »

Instead of having to constantly go back and create a new field every time we need to. Lets just create all required fields.

Creating all the required fields

*You should already be familiar with creating fields*

Client Side
1.   Create a new Enum named “NewsCategories”
Description: News Categories
Values:
1.General
2.Abilities
3.Combat
4.AI
5.GUI
6.Quests
7.Environment
8.Items
9.Inventory

Values are set in a similar way you would add a parent class to a class.



Save the Enum

2.   NewsCategory
Name:NewsCategory
Description:News Categories
Type:enum NewsCategories
Everything else Default

3.   NewsDate
Name:NewsDate
Description:Date of News
Type: datetime
Everything else Default

4.   NewsID
Name:NewsID
Description: ID of news item
Type: id
Everything else Default

5.   NewsItems
*You will not be able to create this field until you create the class "NewsItem"
Name: NewsItems
Description: News Items
Type: lookuplist indexed by id of class NewsItem
Everything else Default

6.   NewsText
Name:NewsText
Description: News text
Type: string
Everything else default

7.   Signature
Name:Signature
Description:Signature to be added at the end of a news entry
Type:string
Everything else Default

Server Side

1.   NextNewsItemID
Name:NextNewsItemID
Description:Tracks news item ids
Type: id
Everything else Default

2.   Copy the Enum "NewsCategories" from the client side to the server side.




3.   Copy NewsCategory from the client side to the server side

4.   Copy NewsDate from the client side to the server side

5.   Copy NewsID from the client side to the server side

6.   Copy NewsText from the client side to the server side

7.   Copy NewsItems from the client side to the server side

8.   Copy signature from client side to server side

You should have every required field now created.

Game News Editor class & other required classes

Creating the class NewsItem & copying it over to the server side
1.   On the client side, create a new class named “NewsItem”
Description: News Item
Archetype: data

2.   Add the following fields to the class
•   NewsCategory
•   NewsDate
•   NewsID
•   NewsText
•   Signature

3.   Click save

That Class is complete
4.   To copy the class over to the server side, click “Copy to Server”


Creating the class “News” & the News Prototype (We will create the client side class, then copy it over to the server side)


Creating the class “News” on the client side part 1

1.   On the client side, create a new class named “News”
Description: News Class
Archetype: data
2.   Add the parent class
•   ObsSubject

3.   And the field
•   NewsItems
4.   Click save

Creating the class “News” on the server side part 1

1.   Go to the client side version(If you are not already there)
2.   Click “Copy to Server”
3.   Go to the server side version of the class “News”
4.   Select the parent class and hit “Delete” on your keyboard



5.   Click save
6.   Add the field
•   NextNewsItemID
7.   Click Save

Before we add the scripts to each of the “News” classes. We need to create a prototype from the class.

Create a prototype from the class

Client Side

Open the console and type the following : | CPFC "News", "News"; description = “News Prototype”

Server Side

Open the console and type the following : \ CPFC "News", "News"; description = “News Prototype”

We are finished creating both our prototypes. We will now finish our “News” class on each side
     
Creating the class “News” on the client side part 2

1.   On the client side, open the class “News”
2.   Click “Open Script”
3.   “Make Empty script”
4.   Type in the following
Code: (hsl) [Select]
#define debug
method News_UpdateNewsItem(item as Class NewsItem)
  //----------------------------
  // Update (or add) a news item
  //----------------------------
  call server %News.News_UpdateNewsItem(item)
.
method News_DeleteNewsItem(item as Class NewsItem)
  //-------------------
  // Delete a news item
  //-------------------
  if me.NewsItems has item.NewsID
    remove item.NewsID from me.NewsItems
  .
  call server %News.News_DeleteNewsItem(item)
 
  me.News_Event_NewsUpdated()
.
remote method News_RecieveNewsItemUpdate(item as Class NewsItem)
  //-------------------------------------------
  // Recieve update for a news item from server
  //-------------------------------------------
  if item.NewsID > 0
    me.NewsItems[item.NewsID] = item
    me.News_Event_NewsItemUpdate(item.NewsID)
  .
.
method News_RequestNewsUpdate()
  //-------------------------------
  // Get all news items from server
  //-------------------------------
  call server %News.News_RequestNewsItems()
.
remote method News_RecieveNewsUpdate(news as LookupList indexed by ID of Class NewsItem)
  //-----------------------------------
  // Recieve all news items for editing
  //-----------------------------------
  me.NewsItems = news
 
  #if debug
    println("News Items Recieved: " + me.NewsItems.length)
  #endif
  me.News_Event_NewsUpdated()
.
method News_Event_NewsUpdated()
  //--------------------------------------------------
  // Inform listeners that entire news feed is updated
  //--------------------------------------------------
  event as NodeRef of Class eventObject = CreateNodeFromClass("eventObject")
  event.eventType = "NEWSUPDATE"
  me.setChanged()
  me.NotifyListeners(event)
.
method News_Event_NewsItemUpdate(newsID as ID)
  event as NodeRef of Class eventObject = CreateNodeFromClass("eventObject")
  event.eventType = "NEWSITEMUPDATE"
  event.eventAffectsID = newsID
  me.setChanged()
  me.NotifyListeners(event) 
.
method News_GetAllNewsItems() as List of Class NewsItem
  keys as List of ID
  foreach key in me.NewsItems
    add back key to keys
  .
  //
  // Bubble sort the keys
  //
  if keys.length > 1
    swapped as Boolean = true
    while swapped
      swapped = false
      loop i from 1 to keys.length - 1
        if me.NewsItems[keys[i]].NewsDate > me.NewsItems[keys[i+1]].NewsDate
          // swap the two items
          var temp = keys[i]
          keys[i] = keys[i+1]
          keys[i+1] = temp
          swapped = true
        .
      .
    .
  .
  sortedNewsItems as List of Class NewsItem
  foreach key in keys
    add back me.NewsItems[key] to sortedNewsItems
  .
  reverseSortedNewsItems as List of Class NewsItem
  foreach item in sortedNewsItems
    add front item to reverseSortedNewsItems
  .
  return reverseSortedNewsItems
.
method News_SortDates(dates references List of DateTime)
  if dates.length > 1
    swapped as Boolean = true
    while swapped
      swapped = false
      loop i from 1 to dates.length - 1
        if dates[i] > dates[i+1]
          // swap the two items
          var temp = dates[i]
          dates[i] = dates[i+1]
          dates[i+1] = temp
          swapped = true
        .
      .
    .
  . 
.
remote method ShowNews()
  NewsWindowClassMethods:open()
.

5.   Compile and Submit

Creating the class “News” on the server side part 2

1.   On the server side, open the class “News”
2.   Click “Open Script”
3.   “Make Empty script”
4.   Type in the following

Code: (hsl) [Select]
untrusted method News_UpdateNewsItem(item as Class NewsItem)
  //--------------------------
  // Update (or add) news item
  //--------------------------
  newItem as Class NewsItem = item
  np as NodeRef of Class News = GetPrototype("News")
  if newItem.NewsID > 0
    //-----------------------------
    // Update to existing news item
    //-----------------------------
    np.NewsItems[newItem.NewsID] = newItem
  else
    //--------------
    // New news item
    //--------------
    newItem.NewsID = np.NextNewsItemID
    np.NewsItems[newItem.NewsID] = newItem
    np.NextNewsItemID = np.NextNewsItemID + 1
  .
  call client SYSTEM.REMOTE.CLIENT %News.News_RecieveNewsItemUpdate(newItem)
.
untrusted method News_DeleteNewsItem(item as Class NewsItem)
  //-------------------------------
  // Delete the specified news item
  //-------------------------------
  np as NodeRef of Class News = GetPrototype("News")
  if item.NewsID > 0
    if np.NewsItems has item.NewsID
      remove item.NewsID from np.NewsItems
    .
  .
.
untrusted method News_RequestNewsItems()
  //------------------------------
  // Send all news items to client
  //------------------------------
  np as NodeRef of Class News = GetPrototype("News")
  call client SYSTEM.REMOTE.CLIENT %News.News_RecieveNewsUpdate(np.NewsItems)
.

5.   Compile and Submit
« Last Edit: Aug 12, 12, 07:33:31 PM by Jrome90 »
Logged

Jrome90

  • General Accounts
  • *
  • Posts: 330
    • View Profile
Re: Porting over the News System from HJRef (Please Not reply yet)
« Reply #3 on: Jan 09, 12, 10:23:32 PM »

Creating the class NewsText

1.   On the client side, create a new class named “NewsText”
Description: News Text
Archetype: guicontrol
2.   Add the parent class
•   GUI9Slice

3.   Click save

4.   Click “Open Script”
5.   Make Empty script
6.   Type up the following script
Code: (hsl) [Select]
method NewsText_SetText(theText as String)
  lbl as NodeRef of Class GUILabel
  lbl = FindGUIControlByName(me, "_Label")
  lbl.text = theText
  lbl.textFormat.wordBreak = true
  me.size.y = GetGUILabelTextSize(lbl).y
 
 
.
That class is complete


We are now finished creating the class “News” on both the client side, and the server side. Next we will go back and submit and compile the script for the class “GameNewsBrowser”

Creating the class “GameNewsBrowser” Part 3

1.   Open up the class “GameNewsBrowser”
2.   Click “OpenScript”
3.   Compile and submit

You should now be able open the Game News Browser by typing the following into the console: call GameNewsBrowserClassMethods open
Finally we are finished with the GameNewsBrowser class. Lets Create the “GameNewsEditor” class.

Creating the class “GameNewsEditor”

1.   On the client side, create a new class named “GameNewsEditor”
Decription: Edit the game news
Archetype: guicontrol

2.   Add the parent class
•   _GUIBaseWindow

3.   Click save

4.   Click “Open Script”
5.   “Make empty script”
6.   Type the following

Code: (hsl) [Select]
method onControlBuild()
  var box = me.GameNews_GetCategoryDropDown()
  var cats = GetEnumValues("NewsCategories")
  box._populateDropDownBox(cats)
  SetKeyboardFocus(me.GameNews_GetNewsTextBox())
 
 
.
method GameNews_GetDateInputBox() as NodeRef of Class GUITextInputBox
  return FindGUIControlByName(me, "scrollable.clientarea._panel9slice._panel1._textInputBox")
.
method GameNews_GetCategoryDropDown() as NodeRef of Class _GUIDropDownBox
  return FindGUIControlByName(me, "scrollable.clientarea._panel9slice._panel2._dropDownBox")
.
method GameNews_GetNewsTextBox() as NodeRef of Class GUITextInputBox
  return FindGUIControlByName(me, "scrollable.clientarea._panel9slice._textInputBox")
.
method GameNews_GetNewsIDLabel() as NodeRef of Class GUILabel
  return FindGUIControlByName(me, "scrollable.clientarea._panel9slice.newsIdLabel")
.
method GameNews_Author() as NodeRef of Class GUILabel
  return FindGUIControlByName(me,"titlebar.author")
.
method GameNews_Populate(item as Class NewsItem)
 
   me.GameNews_GetNewsIDLabel().text = item.NewsID
   me.GameNews_GetDateInputBox().value = item.NewsDate
   me.GameNews_GetCategoryDropDown()._setDropDownBoxValue(item.NewsCategory)
   me.GameNews_GetNewsTextBox().value = item.NewsText
   me.GameNews_Author().text = item.signature
.

method _onButtonMouseClick(btn as NodeRef of Class _GUIButton, args references Class GUIMouseEvent)
  if btn.name = "SaveButton"
      me.GameNews_UpdateGameNews()
    destroynode(me)
  .
.
method GameNews_UpdateGameNews()
  item as Class NewsItem
  item.NewsID = me.GameNews_GetNewsIDLabel().text
  item.NewsDate = me.GameNews_GetDateInputBox().value
  item.NewsCategory = me.GameNews_GetCategoryDropDown()._getDropDownBoxValue()
  item.NewsText = me.GameNews_GetNewsTextBox().value
  item.signature = $BASECLIENT._getMyAccountName()
 
  $News.News_UpdateNewsItem(item)
.



Before we can use the news editor. We need to create the GUI Prototypes. We will just create the remaning GUI XML Prototypes

Creating the remaining XML GUI Prototypes(Copy/Paste)

1.   Create new XML GUI Prototypes for each one below

GameNewsEditor
Code: (xml) [Select]
<createControlType inheritFrom='_window' class='GameNewsEditor' type='GameNewsEditor' description='' treePath='CleanEngine' name="GameNewsEditor">
  <position x="1"/>
  <size x="458" y="560"/>
  <set name="GameNewsEditor.titlebar.title">
    <size x="269"/>
    <set name='GameNewsEditor.titlebar.title' attribute='text' value=" Game News Item Editor"/>
  </set>
  <set name="GameNewsEditor.titlebar">
    <_label name="author" text="Author">
      <position x="262" y="4"/>
      <size x="96" y="19"/>
    </_label>
  </set>
  <set name="GameNewsEditor.scrollable.clientarea">
    <_panel9slice name="_panel9slice" dockMode="FILL">
      <margin rectTop="5" rectBottom="5" rectLeft="5" rectRight="5"/>
      <_label name="_label" dockMode="TOP" text="Date"/>
      <_panel name="_panel1" dockMode="TOP">
        <size x="440" y="20"/>
        <_textInputBox name="_textInputBox" dockMode="LEFT">
          <size x="162"/>
        </_textInputBox>
      </_panel>
      <_label name="_label1" dockMode="TOP" text="Category"/>
      <_panel name="_panel2" dockMode="TOP">
        <size x="440" y="20"/>
        <_dropDownBox name="_dropDownBox">
          <size x="219"/>
        </_dropDownBox>
      </_panel>
      <_label name="_label2" dockMode="TOP" text="Text"/>
      <_panel name="_panel" dockMode="BOTTOM">
        <size x="440" y="41"/>
        <_button name="SaveButton">
          <autoCenter horizontal="true" vertical="true"/>
          <set name='GameNewsEditor.scrollable.clientarea._panel9slice._panel.SaveButton.text' attribute='text' value="Save"/>
        </_button>
      </_panel>
      <_textInputBox name="_textInputBox" dockMode="FILL" isMultiLine="true" historySize="0">
        <area x="440" y="16"/>
      </_textInputBox>
      <_label name="newsIdLabel" visible="false"/>
    </_panel9slice>
  </set>
</createControlType>


NewsWindow
Code: (xml) [Select]
<createControlType inheritFrom='_window' class='NewsWindow' type='NewsWindow' description='' treePath='HJ\BuildingBlocks\Windows' name="NewsWindow" allowTitlebar="false" allowCloseButton="false" allowDragging="false">
  <position x="40" y="18"/>
  <size x="478"/>
  <set name='NewsWindow.titlebar.title' attribute='text' value="GameNameHere"/>
</createControlType>


NewsCategory
Code: (xml) [Select]
<createControlType inheritFrom='_panel9slice' type='NewsCategory' description='' treePath='HJ\BuildingBlocks\Panels' name="NewsCategory">
  <size x="1101" y="23"/>
  <defaultStatePresentation>
    <color a="0"/>
  </defaultStatePresentation>
  <margin rectLeft="20"/>
  <_label name="_label" dockMode="FILL" scale="1.100000024" autoSetHeight="true">
    <defaultStatePresentation>
      <color g="0.5" b="0.5"/>
    </defaultStatePresentation>
  </_label>
</createControlType>

NewsDate
Code: (xml) [Select]
<createControlType inheritFrom='_panel9slice' type='NewsDate' description='' treePath='' name="NewsDate">
  <size x="250"/>
  <defaultStatePresentation>
    <color a="0"/>
  </defaultStatePresentation>
  <margin rectLeft="10"/>
  <_label name="_label" dockMode="FILL" scale="1.25" autoSetHeight="true">
    <defaultStatePresentation>
      <color b="0.5"/>
    </defaultStatePresentation>
  </_label>
</createControlType>

NewsItemConfirmDelete
Code: (xml) [Select]
<createControlType inheritFrom='_window' type='NewsItemConfirmDelete' description='' treePath='CleanEngine' name="NewsItemConfirmDelete">
  <size x="485"/>
  <set name='NewsItemConfirmDelete.titlebar.title' attribute='text' value="Are You Sure?"/>
  <set name="NewsItemConfirmDelete.scrollable.clientarea">
    <_panel name="_panel" dockMode="BOTTOM">
      <size x="462" y="36"/>
      <_button name="ConfirmDeleteButton" script="GameNewsBrowserClassMethods">
        <autoCenter horizontal="true" vertical="true"/>
        <set name='NewsItemConfirmDelete.scrollable.clientarea._panel.ConfirmDeleteButton.text' attribute='text' value="Delete"/>
      </_button>
    </_panel>
  </set>
  <set name="NewsItemConfirmDelete.scrollable.clientarea">
    <_label name="_label" dockMode="TOP" autoSetHeight="true">
      <size x="462" y="16"/>
    </_label>
  </set>
</createControlType>

NewsText
Code: (xml) [Select]
<createControlType class='NewsText' type='NewsText' description='' treePath='' name="NewsText" inheritDisabledState="false" inheritSelectedState="false" inheritHoveringState="false" textureFilter="false">
  <size x="250" y="20"/>
  <maximumSize x="2048" y="2048"/>
  <defaultStatePresentation>
    <color a="0"/>
  </defaultStatePresentation>
  <margin rectLeft="30"/>
  <selectedHoverStatePresentation>
    <color r="0" g="0" b="0" a="0"/>
    <size x="0" y="0"/>
  </selectedHoverStatePresentation>
  <_label name="_label" dockMode="TOP" autoSetHeight="true">
    <size x="220" y="16"/>
  </_label>
</createControlType>

We are really close to being done. Just a few couple more things. We need to create the class “NewsWindow”, and then tell the server to call the client after logging in.

Creating the class “NewsWindow”

1.   On the client side, create a new class named “NewsWindow”
Description: News window gui class
Archetype: guicontrol
2.   Add the parent classes
•   _GUIBaseWindow
•   ObsListener
3.   Click save

4.   Click “Open script”
5.   “Make New Script”
6.   Type the following:

Code: (hsl) [Select]
method onControlBuild()
 
.
remote function RemoteOpen()
  open()
.
method onCloseWindow()
  //-------------------------------------------------
  // User clicked X to close the window, cancel trade
  //-------------------------------------------------
  DestroyNode(me)
.
public function open()

  c as NodeRef of Class GUIControl
  c = CreateNodeFromPrototype("NewsWindow")
  c.build = true
  c.centerControlOver(None)
  c.position.y = 150
  c.size.y = c.size.y * 2
  c.size.x = c.size.x * 1.5
  $News.addListener(c)
  var q = QueryAssociation($News, "base_hard_association", c)
  if q.length > 0
    RemoveAssociation($News, "base_hard_association", c)
  .
 
  $News.News_RequestNewsUpdate()
.
method EventRaised( obs as NodeRef of Class ObsSubject, data as NodeRef )
  where data is kindof eventObject
    #if debug
    println("EventRaised: " + data.eventType)
    #endif
    when data.eventType
      is "NEWSUPDATE"
        me.NewsWindow_Populate()
      .
    .
  .
.
method destroyListener()
  // do not destroy
.
method NewsWindow_GetClientarea() as NodeRef of Class GUIControl
  return FindGUIControlByName(me, "Scrollable.clientarea")
.
method NewsWindow_Populate()
  var clientarea = me.NewsWindow_GetClientarea()
  clear clientarea.children destroy
 
  lbl as NodeRef of Class GUILabel = CreateNodeFromPrototype("_Label")
  lbl.build = true
  lbl.autoSetHeight = false
  lbl.text = "Welcome to <Game Name Here>"
  lbl.scale = 1.5
  lbl.size.y = 25
  lbl.defaultStatePresentation.color.r = 1
  lbl.defaultStatePresentation.color.b = 0.0
  lbl.justification = TOPCENTER
  lbl.dockMode = TOP
  add back lbl to clientarea.children
 
  lbl = CreateNodeFromPrototype("_Label")
  lbl.build = true
  lbl.text = "Recent Changes"
  lbl.scale = 1.25
  lbl.dockMode = TOP
  add back lbl to clientarea.children

  var news = $News.News_GetAllNewsItems()
  theNews as LookupList indexed by String of LookupList indexed by Enum NewsCategories of List of Class NewsItem
 
  foreach item in news
    add back item to theNews[item.NewsDate.dateString][item.NewsCategory]
  .
  dates as List of DateTime
  foreach d in theNews
    add back d to dates
  .
  $News.News_SortDates(dates)
 
  todaysNews as LookupList indexed by Enum NewsCategories of List of Class NewsItem
  categoryNews as List of Class NewsItem
  dateKey as String
 
  loop i from dates.length to 1 by -1
    dateKey = dates[i].dateString
    me.NewsWindow_AddDateLabel(dateKey)
    todaysNews = theNews[dateKey]
    foreach cat in todaysNews
      me.NewsWindow_AddCategoryLabel(cat)
      categoryNews = todaysNews[cat]
      foreach item in categoryNews
        var sig = item.signature
        when sig
          is "<Email>@GMAIL.COM"
            var author = ReplaceString(sig, "<Email>@GMAIL.COM", "<Name>")
            me.NewsWindow_AddNewsLabel(item.NewsText + "$R" +  "~" + author)
          .
          default
             me.NewsWindow_AddNewsLabel(item.NewsText + "$R" +  "~")
          .
        .
      .
    .
  .
.
method NewsWindow_AddDateLabel(theDate as String)
  c as NodeRef of Class GUIControl
  c = CreateNodeFromPrototype("NewsDate")
  c.build = true
  c.dockMode = TOP

  lbl as NodeRef of Class GUILabel = FindGUIControlByName(c, "_Label")
  lbl.text = theDate
 
  var clientarea = me.NewsWindow_GetClientarea()
  add back c to clientarea.children
.
method NewsWindow_AddCategoryLabel(theCat as Enum NewsCategories)
  c as NodeRef of Class GUIControl
  c = CreateNodeFromPrototype("NewsCategory")
  c.build = true
  c.dockMode = TOP
 

  lbl as NodeRef of Class GUILabel = FindGUIControlByName(c, "_Label")
  lbl.text = theCat
 
  var clientarea = me.NewsWindow_GetClientarea()
  add back c to clientarea.children
.
method NewsWindow_AddNewsLabel(theText as String)
  c as NodeRef of Class GUIControl
  c = CreateNodeFromPrototype("NewsText")
  c.build = true
  c.dockMode = TOP
  var clientarea = me.NewsWindow_GetClientarea()
  add back c to clientarea.children
   
  c.NewsText_SetText(theText)
.

Making it so the server can call the client to show the news

1.   On the server side, open the script “E_AccountClassMethods”
2.   Under the following method (At the end) 
Code: (hsl) [Select]
method HE_PostCharacterActivated( theAccount as NodeRef )
3.   Type the following
Code: (hsl) [Select]
if account._IsCharacterSessionStart()
    //If the Client started a new session e.g. Just logged in.
      call client account %News.ShowNews() //Show the News
  .

All we need to do now is make it so we can easily access the game news browser. I know, I said that there was only a couple things left to do.. Well you can stop here.. But if you do then you will have no way to easily access the News browser.

Creating a menu item in the hotspot menu under Tools>Misc
*We are not going to go through the steps needed to create a custom hotspot menu/Utilities Interface*


1.   Open up your custom Utilities Interface in the GUI Editor
2.   In the properties menu click the “+” to expand in the following order
1.   HotSpotGUI
2.   Scrollable
3.   Clientarea
4.   _tabbedParent
5.   Clientarea
6.   Tools
7.   Clientarea
8.   Miscellaneous
9.   Clientarea

3.   Next Click the Gui Control on the bottom. For me it is the “Header Editor”



4.   Go over to the viewport, hit Ctrl+C, and then Ctrl+V (After pressing Ctrl+C the real utilities interface might pop up. Just close it. Then continue)
5.   You will see it create a new control named “_collapsableCategoryItem”
6.   Click on the newly created control and drag it on top of “Clientarea” (See Below)
7.   “_collapsableCategoryItem” will now be a child of “Clientarea”



8.   Under Data Change the name to “News Browser”
9.   And Under Behavior change the script to “GameNewsBrowserClassMethods”



10.   Close Editor and Save
11.   Open your Utilitites interface and rebuild the HotSpot Interface (F5>Commands>Rebuild HotSpot Interface)

Ok, we are finally done. Please once again, if you don’t feel brave enough to follow this. Let me know.
I spent many hours creating this. I do hope it works.

« Last Edit: Aug 12, 12, 07:34:16 PM by Jrome90 »
Logged

Tythin4

  • General Accounts
  • *
  • Posts: 39
    • View Profile
Re: Porting over the News System from HJRef
« Reply #4 on: Jan 10, 12, 07:33:22 PM »

Just got the news working 100%  ;D thanks a lot. The only problem I has was with the Gui xml not making prototypes half the time but I was able to fix that.  This is a pretty good tutorial.
Logged

Jrome90

  • General Accounts
  • *
  • Posts: 330
    • View Profile
Re: Porting over the News System from HJRef
« Reply #5 on: Jan 10, 12, 08:26:46 PM »

Just got the news working 100%  ;D thanks a lot. The only problem I has was with the Gui xml not making prototypes half the time but I was able to fix that.  This is a pretty good tutorial.
No problem, I was not sure if it was going to be worth the time I put into this. But, if even one person appreciated it, I think it was worth it.

Thanks for even attempting this.
Logged

Stadi_Thompson

  • General Accounts
  • *
  • Posts: 324
    • View Profile
Re: Porting over the News System from HJRef
« Reply #6 on: Jan 10, 12, 10:36:42 PM »

Nice tutorial, hope to see all these added to the wiki too.
Logged

JMurdick

  • General Accounts
  • *
  • Posts: 54
    • View Profile
Re: Porting over the News System from HJRef
« Reply #7 on: Jan 11, 12, 09:19:39 AM »

Good tutorial, though if you wanted to improve the system and allow for more designer flexibility I'd recommend converting the NewsCategories from an enum to a Spec.
Logged

runningbird

  • General Accounts
  • *
  • Posts: 37
    • View Profile
    • Runningbird Studios
Re: Porting over the News System from HJRef
« Reply #8 on: Jan 12, 12, 10:32:27 PM »

Got everything done and the Utilities menu only has 2 items now:

Hide All GUIs
Who's Online GUI

When I edit it everything is there?
Logged

Jrome90

  • General Accounts
  • *
  • Posts: 330
    • View Profile
Re: Porting over the News System from HJRef
« Reply #9 on: Jan 13, 12, 12:58:53 AM »

Got everything done and the Utilities menu only has 2 items now:

Hide All GUIs
Who's Online GUI

When I edit it everything is there?

Yes, it should be.
Logged

runningbird

  • General Accounts
  • *
  • Posts: 37
    • View Profile
    • Runningbird Studios
Re: Porting over the News System from HJRef
« Reply #10 on: Jan 14, 12, 11:44:39 AM »

Wohoo I love P4Merge... I was able to revert my GUIXML to the initial version.

For some reason I couldn't copy and paste in the GUI editor so I just did it via the script editor and it worked perfectly.

Thank you so much for this tutorial it cleared up some of the issues I was having understanding the HeroEngine and how to implement certain features etc.

Keep up the tutorials this is exactly what this community needs.
I know once I have something to share I will.
Logged

Neophasis

  • General Accounts
  • *
  • Posts: 6
    • View Profile
Re: Porting over the News System from HJRef
« Reply #11 on: Jan 19, 12, 04:13:26 PM »

Im working through this tutorial and ran into a glitch. 

Quote
Create a prototype from the class

Client Side

Open the console and type the following : | CPFC "News", "News"; description = “News Prototype”

Server Side

Open the console and type the following : \ CPFC "News", "News"; description = “News Prototype”

We are finished creating both our prototypes. We will now finish our “News” class on each side

When I run these commands from the console it returns the following:
Quote
CPFC ERROR 0 : "Parse Error: The Following parameters were unused:
Optional Parameter: description
Optional Parameter: “News
Optional Parameter: Prototype”
Optional Named Parameter: =
"

What am I doing wrong here?
Logged

Jrome90

  • General Accounts
  • *
  • Posts: 330
    • View Profile
Re: Porting over the News System from HJRef
« Reply #12 on: Jan 19, 12, 08:12:11 PM »

Im working through this tutorial and ran into a glitch.  

Quote
Create a prototype from the class

Client Side

Open the console and type the following : | CPFC "News", "News"; description = “News Prototype”

Server Side

Open the console and type the following : \ CPFC "News", "News"; description = “News Prototype”

We are finished creating both our prototypes. We will now finish our “News” class on each side

When I run these commands from the console it returns the following:
Quote
CPFC ERROR 0 : "Parse Error: The Following parameters were unused:
Optional Parameter: description
Optional Parameter: “News
Optional Parameter: Prototype”
Optional Named Parameter: =
"

What am I doing wrong here?

To be Honest, I made a mistake.
To make it work you can just remove the Last part: ;description = “News Prototype”

I am sorry
If you want to have  a description for the prototype. You can go to the "Client Prototypes" right click on the prototype and click on "Info".
There you can enter a description.

« Last Edit: Jan 19, 12, 08:16:47 PM by Jrome90 »
Logged

FI-ScottZ

  • General Accounts
  • *
  • Posts: 1407
    • View Profile
    • Forever Interactive, Inc.
Re: Porting over the News System from HJRef
« Reply #13 on: Jan 19, 12, 08:42:31 PM »

Quote
For some reason I couldn't copy and paste in the GUI editor

Just guessing but it could have been that the viewport didn't have focus at the time.  Without focus on the viewport, the hotkeys are intercepted by HeroBlade instead of going to the script code which is where the copy/paste functionality happens.
Logged
Scott Zarnke
Lead Programmer, Visions of Zosimos
CTO, Forever Interactive, Inc.

LNSBen

  • General Accounts
  • *
  • Posts: 11
    • View Profile
    • LastNight Studio LLC
Re: Porting over the News System from HJRef
« Reply #14 on: Jan 29, 12, 09:21:29 PM »

Under "Creating all the required fields"

Quote
5.   NewsItems
Name: NewsItems
Description: News Items
Type: lookuplist indexed by id of class NewsItem
Everything else Default

I was unable to create this field due to the fact that the "NewsItem" class isn't created until later in the tutorial which caused an error from
Quote
Type: lookuplist indexed by id of class NewsItem

I had to skip ahead and create the NewsItem class then go back to where I left off.  Obviously since I didn't finish creating all the fields yet I didn't finish the step on creating NewsItem, just created it but didn't add the fields to the class until I actually reached that step.

There are a few other areas in the tutorial that are a bit out of order or require a little jumping around but I got it working in the end.  Best advice is if a script wont compile you may have to wait until another script is compiled and submitted before the current one will or you may have to comment out problem sections and then come back and uncomment later. 

Working great now, thanks.
« Last Edit: Jan 29, 12, 10:38:45 PM by Ben »
Logged
Ben W.
Member Owner / Producer
LastNight Studio LLC
Pages: [1] 2 3