<commit_before>CocoClass = require 'lib/CocoClass'
{createProgressBar} = require './sprite_utils'
Camera = require './Camera'
Mark = require './Mark'
Label = require './Label'
AudioPlayer = require 'lib/AudioPlayer'
{me} = require 'lib/auth'

# We'll get rid of this once level's teams actually have colors
healthColors =
  ogres: [64, 128, 212]
  humans: [255, 0, 0]
  neutral: [64, 212, 128]

# Sprite: EaselJS-based view/controller for Thang model
module.exports = CocoSprite = class CocoSprite extends CocoClass
  thangType: null # ThangType instance

  imageObject: null

  healthBar: null
  marks: null
  labels: null
  ranges: null

  options:
    resolutionFactor: SPRITE_RESOLUTION_FACTOR
    groundLayer: null
    textLayer: null
    floatingLayer: null
    frameRateFactor: 1  # TODO: use or lose?
    thang: null
    camera: null
    spriteSheetCache: null
    showInvisible: false

  possessed: false
  flipped: false
  flippedCount: 0
  actionQueue: null
  actions: null
  rotation: 0

  # Scale numbers
  baseScaleX: 1 # scale + flip (for current action) / resolutionFactor.
  baseScaleY: 1 # These numbers rarely change, so keep them around.
  scaleFactor: 1 # Current scale adjustment. This can change rapidly.
  targetScaleFactor: 1 # What the scaleFactor is going toward during a tween.

  # ACTION STATE
  # Actions have relations. If you say 'move', 'move_side' may play because of a direction
  # relationship, and if you say 'cast', 'cast_begin' may happen first, or 'cast_end' after.
  currentRootAction: null  # action that, in general, is playing or will play
  currentAction: null  # related action that is right now playing

  subscriptions:
    'level-sprite-dialogue': 'onDialogue'
    'level-sprite-clear-dialogue': 'onClearDialogue'
    'level-set-letterbox': 'onSetLetterbox'
    'surface:ticked': 'onSurfaceTicked'
    'level-sprite-move': 'onMove'

  constructor: (@thangType, options) ->
    super()
    @options = _.extend($.extend(true, {}, @options), options)
    @setThang @options.thang
    console.error @toString(), "has no ThangType!" unless @thangType

    # this is a stub, use @setImageObject to swap it out for something else later
    @imageObject = new createjs.Container

    @actionQueue = []
    @marks = {}
    @labels = {}
    @ranges = []
    @handledDisplayEvents = {}
    @age = 0
    if @thangType.isFullyLoaded()
      @setupSprite()
    else
      @stillLoading = true
      @thangType.fetch()
      @listenToOnce(@thangType, 'sync', @setupSprite)

  setupSprite: ->
    for trigger, sounds of @thangType.get('soundTriggers') or {} when trigger isnt 'say'
      AudioPlayer.preloadSoundReference sound for sound in sounds
    @stillLoading = false
    if @thangType.get('raster')
      @actions = {}
      @isRaster = true
      @setUpRasterImage()
    else
      @actions = @thangType.getActions()
      @buildFromSpriteSheet @buildSpriteSheet()
      @createMarks()

  finishSetup: ->
    return unless @thang
    @updateBaseScale()
    @update true  # Reflect initial scale and other state

  setUpRasterImage: ->
    raster = @thangType.get('raster')
    image = new createjs.Bitmap('/file/'+raster)
    @setImageObject image
    $(image.image).one 'load', => @updateScale?()
    @configureMouse()
    @imageObject.sprite = @
    @imageObject.layerPriority = @thangType.get 'layerPriority'
    @imageObject.name = @thang?.spriteName or @thangType.get 'name'
    reg = @getOffset 'registration'<commit_msg>Fixed a bug with thangs not being properly scaled when first created sometimes.<commit_after>CocoClass = require 'lib/CocoClass'
{createProgressBar} = require './sprite_utils'
Camera = require './Camera'
Mark = require './Mark'
Label = require './Label'
AudioPlayer = require 'lib/AudioPlayer'
{me} = require 'lib/auth'

# We'll get rid of this once level's teams actually have colors
healthColors =
  ogres: [64, 128, 212]
  humans: [255, 0, 0]
  neutral: [64, 212, 128]

# Sprite: EaselJS-based view/controller for Thang model
module.exports = CocoSprite = class CocoSprite extends CocoClass
  thangType: null # ThangType instance

  imageObject: null

  healthBar: null
  marks: null
  labels: null
  ranges: null

  options:
    resolutionFactor: SPRITE_RESOLUTION_FACTOR
    groundLayer: null
    textLayer: null
    floatingLayer: null
    frameRateFactor: 1  # TODO: use or lose?
    thang: null
    camera: null
    spriteSheetCache: null
    showInvisible: false

  possessed: false
  flipped: false
  flippedCount: 0
  actionQueue: null
  actions: null
  rotation: 0

  # Scale numbers
  baseScaleX: 1 # scale + flip (for current action) / resolutionFactor.
  baseScaleY: 1 # These numbers rarely change, so keep them around.
  scaleFactor: 1 # Current scale adjustment. This can change rapidly.
  targetScaleFactor: 1 # What the scaleFactor is going toward during a tween.

  # ACTION STATE
  # Actions have relations. If you say 'move', 'move_side' may play because of a direction
  # relationship, and if you say 'cast', 'cast_begin' may happen first, or 'cast_end' after.
  currentRootAction: null  # action that, in general, is playing or will play
  currentAction: null  # related action that is right now playing

  subscriptions:
    'level-sprite-dialogue': 'onDialogue'
    'level-sprite-clear-dialogue': 'onClearDialogue'
    'level-set-letterbox': 'onSetLetterbox'
    'surface:ticked': 'onSurfaceTicked'
    'level-sprite-move': 'onMove'

  constructor: (@thangType, options) ->
    super()
    @options = _.extend($.extend(true, {}, @options), options)
    @setThang @options.thang
    console.error @toString(), "has no ThangType!" unless @thangType

    # this is a stub, use @setImageObject to swap it out for something else later
    @imageObject = new createjs.Container

    @actionQueue = []
    @marks = {}
    @labels = {}
    @ranges = []
    @handledDisplayEvents = {}
    @age = 0
    if @thangType.isFullyLoaded()
      @setupSprite()
    else
      @stillLoading = true
      @thangType.fetch()
      @listenToOnce(@thangType, 'sync', @setupSprite)

  setupSprite: ->
    for trigger, sounds of @thangType.get('soundTriggers') or {} when trigger isnt 'say'
      AudioPlayer.preloadSoundReference sound for sound in sounds
    @stillLoading = false
    if @thangType.get('raster')
      @actions = {}
      @isRaster = true
      @setUpRasterImage()
    else
      @actions = @thangType.getActions()
      @buildFromSpriteSheet @buildSpriteSheet()
      @createMarks()

  finishSetup: ->
    return unless @thang
    @updateBaseScale()
    @scaleFactor = @thang.scaleFactor if @thang?.scaleFactor
    @update true  # Reflect initial scale and other state

  setUpRasterImage: ->
    raster = @thangType.get('raster')
    image = new createjs.Bitmap('/file/'+raster)
    @setImageObject image
    $(image.image).one 'load', => @updateScale?()
    @configureMouse()
    @imageObject.sprite = @
    @imageObject.layerPriority = @thangType.get 'layerPriority'
    @imageObject.name = @thang?.spriteName or @thangType.get 'name'
    reg = @getOffset 'registration'
{'fraction_non_alphanumeric': 0.10669308051507004, 'fraction_numerical': 0.008207160039620772, 'mean_word_length': 3.5394990366088632, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6180326', 'n_tokens_mistral': 2258, 'n_tokens_neox': 2184, 'n_words': 665}