engagementgamelab/CivicSeed

View on GitHub
server/rpc/admin/npcs.js

Summary

Maintainability
F
3 days
Test Coverage
'use strict'

var winston = require('winston')

// Define actions which can be called from the client using ss.rpc('demo.ACTIONNAME', param1, param2...)
exports.actions = function (req, res, ss) {
  req.use('session')

  var npcModel = ss.service.db.model('Npc')
  var tileModel = ss.service.db.model('Tile')

  // TODO BUG
  // This does not properly save the y-1 tile with the correct NPC state and ID
  // Most of this should be refactored anyway because this is callback hell

  var npcHelpers = {
    addNpcTile: function (position, callback) {
      tileModel
        .where('x').equals(position.x)
        .where('y').equals(position.y)
        .find(function (err, tiles) {
          if (err) {
            callback('There was an error finding the tile in the database. Please check server logs.')
            winston.error('admin.npcs.addNpcTile: ' + err)
          } else if (tiles && tiles.length > 0) {
            if (tiles[0].tileState === 0) {
              tiles[0].tileState = 2
              tiles[0].save(function (err, saved) {
                if (err) {
                  callback('could not save tile')
                } else if (saved) {
                  callback()
                }
              })
            }
          } else {
            callback('Could not add NPC.<br>x, y coordinates are not valid.')
          }
        })
    },

    removeNpcTile: function (position, callback) {
      tileModel
        .where('x').equals(position.x)
        .where('y').equals(position.y)
        .find(function (err, tiles) {
          if (err) {
            callback('could not find tile')
          } else if (tiles) {
            // Restore tilestate to zero
            // Note: NPCs are only allowed to occupy go-tiles (state = 0)
            tiles[0].tileState = 0
            tiles[0].save(function (err, saved) {
              if (err) {
                callback('could not save tile')
              } else if (saved) {
                callback()
              }
            })
          }
        })
    },

    updateTiles: function (oldPosition, newPosition, callback) {
      // update new tile, make sure we can change it
      if ((oldPosition.x === newPosition.x) && (oldPosition.y === newPosition.y)) {
        callback()
      } else {
        tileModel
          .where('x').equals(newPosition.x)
          .where('y').equals(newPosition.y)
          .find(function (err, newTiles) {
            if (err) {
              callback('could not find new tile')
            } else if (newTiles) {
              if (newTiles[0].tileState === 0) {
                newTiles[0].tileState = 2
                newTiles[0].save(function (err, saved) {
                  if (err) {
                    callback('could not save new tiles')
                  } else if (saved) {
                    // update the old tile so it doesnt have an npc
                    tileModel
                      .where('x').equals(oldPosition.x)
                      .where('y').equals(oldPosition.y)
                      .find(function (err, oldTiles) {
                        if (err) {
                          callback('could not find old tile')
                        } else if (oldTiles) {
                          oldTiles[0].tileState = 0
                          oldTiles[0].save(function (err, saved) {
                            if (err) {
                              callback('could not save old tiles')
                            } else if (saved) {
                              callback()
                            }
                          })
                        }
                      })
                  }
                })
              } else {
                callback('cant place npc there')
              }
            }
          })
      }
    }
  }

  return {
    init: function (id) {
      npcModel
        .find()
        .sort('level')
        .exec(function (err, result) {
          if (err) {
            res(err)
          } else if (result) {
            res(result)
          }
        })
    },

    updateInformation: function (info) {
      npcModel
        .where('id').equals(info.id)
        .find(function (err, result) {
          if (err) {
            res('error:' + err)
          } else if (result) {
            var npc = result[0]

            // update the tiles for the npc
            npcHelpers.updateTiles(npc.position, info.position, function (error) {
              if (error) {
                res(error)
              } else {
                // general
                npc.name = info.name
                npc.sprite = info.sprite
                npc.isHolding = info.isHolding
                npc.level = info.level
                npc.skinSuit = info.skinSuit

                npc.position = info.position

                // resource
                if (info.isHolding) {
                  npc.resource.id = parseInt(info.resource.url, 10) // TODO: Change
                  npc.resource.url = info.resource.url
                  npc.resource.questionType = info.resource.questionType
                  npc.resource.question = info.resource.question
                  npc.resource.shape = info.resource.shape
                  npc.resource.feedbackRight = info.resource.feedbackRight
                  npc.resource.feedbackWrong = info.resource.feedbackWrong
                  npc.dialog.prompts = info.dialog.prompts
                  npc.dependsOn = info.dependsOn

                  // not open
                  if (info.questionType === 'open') {
                    npc.resource.requiredLength = info.resource.requiredLength
                  } else {
                    npc.resource.answer = info.resource.answer
                    if (info.resource.questionType === 'multiple') {
                      npc.resource.possibleAnswers = info.resource.possibleAnswers
                    }
                  }
                } else {
                  // smalltalk
                  npc.dialog.smalltalk = info.dialog.smalltalk
                }

                npc.save(function (err, okay) {
                  if (err) {
                    res('error')
                  } else {
                    res(false)
                  }
                })
              }
            })
          }
        })
    },

    addNpc: function (info) {
      npcModel
        .create(info, function (err, result) {
          if (err) {
            res(err)
          } else if (result) {
            npcHelpers.addNpcTile(info.position, function (err) {
              res(err)
            })
          }
        })
    },

    deleteNpc: function (id) {
      npcModel
        .where('id').equals(id)
        .find(function (err, npc) {
          if (err) {
            res(err)
          } else if (npc) {
            var position = npc[0].position
            npcModel
              .where('id').equals(id)
              .remove(function (err, result) {
                if (err) {
                  res(err)
                } else {
                  npcHelpers.removeNpcTile(position, function (err) {
                    res(err)
                  })
                }
              })
          }
        })
    }
  }
}