1818
1919import { CharacterInputController } from "./characterInputController" ;
2020import { World } from "./world" ;
21- import { Collidable , CollidableType } from "./collidable" ;
21+ import { Collidable , CollidableCategory } from "./collidable" ;
2222import { CollidableTypes } from "../levelpack/levelpack" ;
2323import { Skill } from "./skill" ;
2424import { Item } from "./item" ;
2525import { InventorySlot } from "./inventory" ;
26- import { Quaternion , Vector3 } from "./math" ;
26+ import { Quaternion , Ray , RayPickingInfo , Vector3 } from "./math" ;
2727
2828/**
2929 * A character in the game world. Can be an Ally, an Enemy, or both. Can be a Player or an NPC.
3030 */
3131export class Character {
32- protected _characterWorld ! : World ;
33- protected _characterInputController ! : CharacterInputController ;
32+ protected _characterWorld : World ;
33+ protected _characterInputController : CharacterInputController ;
3434
3535 // Character Location and Rotation
3636 protected _characterPosition ! : Vector3 ;
@@ -54,16 +54,16 @@ export class Character {
5454 protected _characterNormalGravititationalAcceleration : number = - 1.0 ;
5555
5656 // Character State
57- protected _healthPoints ! : number ;
58- protected _manaPoints ! : number ;
57+ protected _healthPoints : number ;
58+ protected _manaPoints : number ;
5959
6060 protected _canWallJumpNow : boolean = true ;
61- protected _lastWallWallJumpedFrom : Collidable = null ;
61+ protected _lastWallWallJumpedFrom : Collidable | null = null ;
6262 protected _jumpState : boolean = false ;
6363 /**
6464 * A map from a world surface type to a boolean
6565 */
66- public readonly isCharacterOnWorldSurface : Map < CollidableType , boolean > = new Map ( [ ] ) ;
66+ public readonly isCharacterOnWorldSurface : Map < CollidableCategory , boolean > = new Map ( ) ;
6767
6868 /**
6969 * An array of skills this character is using right now.
@@ -181,7 +181,7 @@ export class Character {
181181 return this . _canWallJumpNow ;
182182 }
183183
184- public get lastWallWallJumpedFrom ( ) : Collidable {
184+ public get lastWallWallJumpedFrom ( ) : Collidable | null {
185185 return this . _lastWallWallJumpedFrom ;
186186 }
187187
@@ -207,7 +207,7 @@ export class Character {
207207 }
208208
209209 protected checkCollisions ( ) : void {
210- this . isCharacterOnWorldSurface . forEach ( ( _value : boolean , collidableType : CollidableType ) => {
210+ this . isCharacterOnWorldSurface . forEach ( ( _value : boolean , collidableType : CollidableCategory ) => {
211211 this . isCharacterOnWorldSurface . set ( collidableType , false ) ;
212212 } )
213213 this . _characterWorld . collidables . forEach ( ( collidable ) => {
@@ -368,33 +368,25 @@ export class Character {
368368 this . applyGravity ( getDeltaTime ) ;
369369 this . capYVelocity ( ) ;
370370
371- let deltaPos = this . _characterVelocity . scale ( getDeltaTime ( ) / 1000.0 ) ;
371+ let deltaPos : Vector3 = ( getDeltaTime ( ) / 1000.0 ) * this . _characterVelocity ;
372372
373373 if ( deltaPos . length ( ) > 0 ) {
374- let ray : Ray = new Ray ( this . _characterPosition , deltaPos . normalizeToNew ( ) , this . _characterHeight / 2 ) ;
375- this . movementRayHelper = new RayHelper ( ray ) ;
376- this . movementRayHelper . show (
377- this . _characterWorld . babylonScene ,
378- Color3 . Purple ( )
379- ) ;
380- let hit : Nullable < PickingInfo > = this . _characterWorld . babylonScene . pickWithRay ( ray ,
381- ( mesh : AbstractMesh ) => {
382- return this . _characterWorld . collidables
383- . map ( ( collidable ) => collidable . babylonMesh ) . includes ( mesh ) ;
374+ let ray : Ray = new Ray ( this . _characterPosition , deltaPos . normalize ( ) , this . _characterHeight / 2 ) ;
375+ let hit : RayPickingInfo = this . _characterWorld . pickWithRay ( ray ,
376+ ( collidable : Collidable ) : boolean => {
377+ return this . _characterWorld . collidables . indexOf ( collidable ) > 0 ;
384378 } ) ;
385- if ( hit && hit . pickedPoint && hit . getNormal ( true ) ) {
386- console . debug ( hit , hit . getNormal ( true ) )
387- this . _babylonMesh . position = this . _characterPosition =
388- hit . pickedPoint . add ( hit . getNormal ( true ) ! . scale ( this . _characterHeight / 2 ) ) ;
389- this . _characterVelocity = this . _characterVelocity
390- . subtract ( hit . getNormal ( true ) ! . scale ( this . _characterVelocity . dot ( hit . getNormal ( true ) ! ) ) ) ;
391-
379+ if ( hit && hit . getHitPosition ( ) && hit . getNormalVector ( ) ) {
380+ console . debug ( hit , hit . getNormalVector ( ) )
381+ this . _characterPosition =
382+ hit . getHitPosition ( ) + ( this . _characterHeight / 2 ) * hit . getNormalVector ( ) ! ;
383+ this . _characterVelocity = this . _characterVelocity -
384+ Vector3 . dot ( this . _characterVelocity , hit . getNormalVector ( ) ! ) * hit . getNormalVector ( ) ! ;
392385 } else {
393- this . _babylonMesh . position = this . _characterPosition = this . _characterPosition . add ( deltaPos ) ;
386+ this . _characterPosition = this . _characterPosition + deltaPos ;
394387 }
395388 }
396- console . assert ( ! ! this . _babylonMesh . rotationQuaternion , "Rotation quaternion cannot be undefined" ) ;
397- this . _characterOrientation = this . _babylonMesh . rotationQuaternion as Quaternion ;
389+ console . assert ( ! ! this . _characterOrientation , "Rotation quaternion cannot be undefined" ) ;
398390 this . checkCollisions ( ) ;
399391 this . applyGravity ( getDeltaTime ) ;
400392 this . capYVelocity ( ) ;
@@ -409,4 +401,116 @@ export class Character {
409401 protected get horizontalMovementScaleFactor ( ) : number {
410402 return this . isCharacterOnWorldSurface . get ( CollidableTypes . GROUND ) ? 5.0 : 1.0 ;
411403 }
404+ }
405+
406+ export function newCharacter ( characterHeight : number , characterWorld : World ,
407+ characterInputController : CharacterInputController ) : Character {
408+ return new Character ( characterHeight , characterWorld , characterInputController ) ;
409+ }
410+
411+ /**
412+ * The world the character is currently in.
413+ */
414+ export function getCharacterWorld ( target : Character ) : World {
415+ return target . characterWorld ;
416+ }
417+
418+ export function getCharacterInputController ( target : Character ) : CharacterInputController {
419+ return target . characterInputController ;
420+ }
421+
422+
423+ // Character Location and Rotation
424+ /**
425+ * Character position in 3D Space.
426+ */
427+ export function getCharacterPosition ( target : Character ) : Vector3 {
428+ return target . characterPosition ;
429+ }
430+
431+ /**
432+ * Character Velocity in 3D Space.
433+ */
434+ export function getCharacterVelocity ( target : Character ) : Vector3 {
435+ return target . characterVelocity ;
436+ }
437+
438+ /**
439+ * Character Orientation in 3D Space (as a Quaternion)
440+ */
441+ export function getCharacterOrientation ( target : Character ) : Quaternion {
442+ return target . characterOrientation ;
443+ }
444+
445+ /**
446+ * Character Ray of View in 3D Space
447+ */
448+ export function getCharacterRayOfView ( target : Character ) : Vector3 {
449+ return target . characterRayOfView ;
450+ }
451+
452+ // Character Properties
453+ export function getCharacterHeight ( target : Character ) : number {
454+ return target . characterHeight ;
455+ }
456+
457+ export function getCharacterMaximumHealthPoints ( target : Character ) : number {
458+ return target . characterMaximumHealthPoints ;
459+ }
460+
461+ export function getCharacterMaximumManaPoints ( target : Character ) : number {
462+ return target . characterMaximumManaPoints ;
463+ }
464+
465+ export function getCharacterMaximumSkillPoints ( target : Character ) : number {
466+ return target . characterMaximumSkillPoints ;
467+ }
468+
469+ export function getCharacterMaximumHorizontalSpeedUponJoystickNeutral ( target : Character ) : number {
470+ return target . characterMaximumHorizontalSpeedUponJoystickNeutral ;
471+ }
472+
473+ export function getCharacterMaximumHorizontalSpeedUponJoystickFullyActive ( target : Character ) : number {
474+ return target . characterMaximumHorizontalSpeedUponJoystickFullyActive ;
475+ }
476+
477+ export function getCharacterMaximumVerticalSpeed ( target : Character ) : number {
478+ return target . characterMaximumVerticalSpeed ;
479+ }
480+
481+ export function getCharacterVerticalJumpVelocity ( target : Character ) : number {
482+ return target . characterVerticalJumpVelocity ;
483+ }
484+
485+ export function getCharacterGroundFriction ( target : Character ) : number {
486+ return target . characterGroundFriction ;
487+ }
488+
489+ // Character State
490+ export function getCharacterHealthPoints ( target : Character ) : number {
491+ return target . healthPoints ;
492+ }
493+
494+ export function getCharacterManaPoints ( target : Character ) : number {
495+ return target . manaPoints ;
496+ }
497+
498+ export function getCharacterCanWallJumpNow ( target : Character ) : boolean {
499+ return target . canWallJumpNow ;
500+ }
501+
502+ export function getCharacterLastWallWallJumpedFrom ( target : Character ) : Collidable | null {
503+ return target . lastWallWallJumpedFrom ;
504+ }
505+
506+ export function getCharacterJumpState ( target : Character ) : boolean {
507+ return target . jumpState ;
508+ }
509+
510+ export function setCharacterPositionAndRotation (
511+ target : Character ,
512+ pos : Vector3 ,
513+ rot : Quaternion
514+ ) : Character {
515+ return target . setPositionAndRotation ( pos , rot ) ;
412516}
0 commit comments