// Release event may be accompained by a set animation event and set anchored position. // It safely releases at the relative position to parent, taking physics in consideration public static void ReleaseAnchoredEntity(GameEntityModel model, GameEntityModel anchoredEntityModel){ int anchorId = -1; for (int i = 0; i < model.anchoredEntities.Count ; ++i){ if (model.anchoredEntities[i] == anchoredEntityModel.Index){ anchorId = i; break; } } if (anchorId == -1){ // entity is not grabbed, return return; } anchoredEntityModel.parentEntity = new ModelReference(); PhysicPointModel pointModel = GameEntityController.GetPointModel(anchoredEntityModel); if (pointModel != null){ pointModel.isActive = true; PhysicPointModel parentPointModel = GameEntityController.GetPointModel(model); PhysicPointController pointController = pointModel.Controller() as PhysicPointController; if (pointController != null && parentPointModel != null){ // Set position directly pointModel.position = parentPointModel.position; if (!model.IsFacingRight()) anchoredEntityModel.positionRelativeToParent.X *= -1; pointController.SetVelocityAffector(pointModel, PhysicPointController.setPositionffectorName, anchoredEntityModel.positionRelativeToParent); anchoredEntityModel.positionRelativeToParent = FixedVector3.Zero; } } model.anchoredEntities[anchorId] = new ModelReference(); }
// 5: GetHitters private static EventSubject <GameEntityModel> .GetSubjectsDelegate GetHitters(Storage.GenericParameter parameter) { // Read orientation options, types options, list of types, collision ids options, collision ids list OrientationOptions orientationOptions = (OrientationOptions)parameter.SafeInt(1); AnyOrAllOptions typesOptions = (AnyOrAllOptions)parameter.SafeInt(2); int[] types = parameter.SafeIntsList(0); AnyOrAllOptions collisionIdsOptions = (AnyOrAllOptions)parameter.SafeInt(3); int[] collisionIds = parameter.SafeIntsList(1); int subjectId = parameter.SafeInt(0); return(DefaultDelegation(subjectId, delegate(GameEntityModel model, List <GameEntityModel> subjects){ GameEntityController controller = model.Controller() as GameEntityController; List <HitInformation> hurts = controller.lastHurts; GameEntityModel subject; foreach (HitInformation hitInformation in hurts) { if (isHitConformingType(hitInformation, typesOptions, types) && isHitConformingCollisionId(hitInformation, collisionIdsOptions, collisionIds) ) { subject = getHitEntityIfConformingOrientationOptions(hitInformation, orientationOptions, model); if (subject != null) { subjects.Add(subject); } } } })); }
// Check collisions between all entities of the two given teams private void CheckCollisions(List <ModelReference> team1Refs, List <ModelReference> team2Refs) { GameEntityModel entity1, entity2; GameEntityController entity1Controller; State gameState = StateManager.state; foreach (ModelReference team1EntityRef in team1Refs) { entity1 = gameState.GetModel(team1EntityRef) as GameEntityModel; if (entity1 != null && !GameEntityController.IsCollidingWithOthers(entity1)) { entity1Controller = entity1.Controller() as GameEntityController; if (entity1Controller != null) { foreach (ModelReference team2EntityRef in team2Refs) { entity2 = gameState.GetModel(team2EntityRef) as GameEntityModel; if (entity2 != null && entity2 != entity1 && (entity2.parentEntity == null || entity2.parentEntity != entity1.Index) && (entity1.parentEntity == null || entity1.parentEntity != entity2.Index) && (entity2.ownerEntity == null || entity2.ownerEntity != entity1.Index) && (entity1.ownerEntity == null || entity1.ownerEntity != entity2.Index) && entity1Controller.CollisionCollisionCheck(entity1, entity2) ) { // collision detected for this entity, no need for further checks break; } // if collision check } // foreach team2 entity } // entity1 controller != null } // entity1 != null & not colliding } // foreach entity 1 } // method check collision
// Filter hit by hitter entity location private static GameEntityModel getHitEntityIfConformingOrientationOptions(HitInformation hit, OrientationOptions orientationOptions, GameEntityModel model) { GameEntityModel hitterModel = StateManager.state.GetModel(hit.entityId) as GameEntityModel; if (orientationOptions == OrientationOptions.any) { return(hitterModel); } PhysicPointModel modelPoint = GameEntityController.GetPointModel(model); PhysicPointModel hitterPoint = GameEntityController.GetPointModel(hitterModel); bool isFrontal; if (model.IsFacingRight()) { isFrontal = hitterPoint.position.X >= modelPoint.position.X; } else { isFrontal = hitterPoint.position.X <= modelPoint.position.X; } if (isFrontal == (orientationOptions == OrientationOptions.fromFront)) { return(hitterModel); } return(null); }
// 6: GetHittens private static EventSubject <GameEntityModel> .GetSubjectsDelegate GetHittens(Storage.GenericParameter parameter) { // Read types options, list of types, hit ids options, hit ids list AnyOrAllOptions typesOptions = (AnyOrAllOptions)parameter.SafeInt(1); int[] types = parameter.SafeIntsList(0); AnyOrAllOptions hitIdsOptions = (AnyOrAllOptions)parameter.SafeInt(2); int[] hitIds = parameter.SafeIntsList(1); int subjectId = parameter.SafeInt(0); return(DefaultDelegation(subjectId, delegate(GameEntityModel model, List <GameEntityModel> subjects){ GameEntityController controller = model.Controller() as GameEntityController; List <HitInformation> hits = controller.lastHits; GameEntityModel subject; foreach (HitInformation hitInformation in hits) { if (isHitConformingType(hitInformation, typesOptions, types) && isHitConformingHitId(hitInformation, hitIdsOptions, hitIds) ) { subject = StateManager.state.GetModel(hitInformation.entityId) as GameEntityModel; subjects.Add(subject); } } })); }
// Parent name (who's anchoring the entity) public static string ParentEntityName(GameEntityModel model){ GameEntityModel parentEntityModel = StateManager.state.GetModel(model.parentEntity) as GameEntityModel; if (parentEntityModel == null) return null; AnimationModel animModel = GameEntityController.GetAnimationModel(parentEntityModel); if (animModel == null) return null; return animModel.characterName; }
// Successful hits a team public static bool HitTeam(GameEntityModel model, InclusionType teamInclusionType, int teamId, InclusionType typeInclusionType, int type) { GameEntityController controller = model.Controller() as GameEntityController; if (controller.lastHits.Count == 0) { return(false); } bool isValid = false; // Check team foreach (HitInformation hit in controller.lastHits) { if (InclusionCheck(teamInclusionType, WorldUtils.GetEntityTeam(hit.entityId), teamId, out isValid)) { break; } } if (!isValid) { return(false); } // Check type foreach (HitInformation hit in controller.lastHits) { if (InclusionCheck(typeInclusionType, (int)hit.hitData.type, type, out isValid)) { break; } } return(isValid); }
public static void HurtBasedOnFacingOptions(GameEntityModel model, HitData.HitFacing facingOptions, FixedFloat damagePercentage, List <GameEntityModel> hitterSubjects = null) { // Facing if (facingOptions == HitData.HitFacing.hitterLocation || facingOptions == HitData.HitFacing.inverseHitterLocation) { FaceToHitterLocation(model, facingOptions == HitData.HitFacing.inverseHitterLocation); } else if (facingOptions == HitData.HitFacing.hitterOrientation || facingOptions == HitData.HitFacing.inverseHitterOrientation) { FaceToHitterDirection(model, facingOptions == HitData.HitFacing.inverseHitterOrientation); } else { // None, nothing to do } // Damage! if (damagePercentage != 0 && model.customVariables.ContainsKey("energy")) { GameEntityController controller = model.Controller() as GameEntityController; foreach (HitInformation hitInfo in controller.lastHurts) { if (hitterSubjects == null || hitterSubjects.Find(x => x.Index == hitInfo.entityId) != null) { int damageValue = (int)(hitInfo.hitData.damage * damagePercentage); if (damageValue == 0) { damageValue = 1; } model.customVariables["energy"] -= damageValue; } } } }
// Anchor a model to it public static void AnchorEntity(GameEntityModel model, GameEntityModel modelToBeAnchored, int anchorId){ if (IsAnchored(modelToBeAnchored)){ Debug.LogWarning("Trying to anchor an entity that is already anchored"); return; } if (model.parentEntity != null && model.parentEntity == modelToBeAnchored.Index){ Debug.LogWarning("Cyclic anchoring attempt"); return; } if (model.anchoredEntities == null) model.anchoredEntities = new List<ModelReference>(anchorId); while (model.anchoredEntities.Count <= anchorId) { model.anchoredEntities.Add(null); } if (model.anchoredEntities[anchorId] != null && model.anchoredEntities[anchorId] != ModelReference.InvalidModelIndex){ Debug.LogWarning("Trying to anchor an entity to a busy anchor"); return; } model.anchoredEntities[anchorId] = modelToBeAnchored.Index; modelToBeAnchored.parentEntity = model.Index; modelToBeAnchored.positionRelativeToParent = FixedVector3.Zero; PhysicPointModel pointModel = GameEntityController.GetPointModel(modelToBeAnchored); if (pointModel != null){ pointModel.isActive = false; } }
private static EventAction <GameEntityModel> .ExecutionDelegate BuildGetHurt(Storage.GenericParameter parameter) { int hittersSubjectId = parameter.SafeInt(1); int numeratorSubjectId = parameter.SafeInt(2); string numeratorVariableName = parameter.SafeString(0); int defaultPercentage = parameter.SafeInt(3); int facingOptions = parameter.SafeInt(4); return(delegate(GameEntityModel model, List <GameEntityModel>[] subjectModels){ List <GameEntityModel> hitterSubjects = ConditionUtils <GameEntityModel> .GetNonEmptySubjectOrNil(subjectModels, hittersSubjectId); if (hitterSubjects == null || hitterSubjects.Count == 0) { return; } FixedFloat percentage = GetNumeratorValue(model, numeratorSubjectId, numeratorVariableName, defaultPercentage, subjectModels); percentage /= 100; switch (facingOptions) { case -1: // Use hit data GameEntityController.HurtBasedOnHitData(model, percentage, hitterSubjects); break; default: // Use given facing options GameEntityController.HurtBasedOnFacingOptions(model, (HitData.HitFacing)facingOptions, percentage, hitterSubjects); break; } }); }
private static EventAction <GameEntityModel> .ExecutionDelegate BuildSetAutoFlip(Storage.GenericParameter parameter) { bool autoValue = parameter.SafeBool(0); return(delegate(GameEntityModel model, List <GameEntityModel>[] subjectModels){ GameEntityController.SetAutomaticFlip(model, autoValue); }); }
// Anchored animation name public static string AnchoredEntityAnimation(GameEntityModel model, int anchorId){ if (model.anchoredEntities == null || model.anchoredEntities.Count <= anchorId || model.anchoredEntities[anchorId] == null) return null; GameEntityModel anchoredEntityModel = StateManager.state.GetModel(model.anchoredEntities[anchorId]) as GameEntityModel; if (anchoredEntityModel == null) return null; AnimationModel animModel = GameEntityController.GetAnimationModel(anchoredEntityModel); if (animModel == null) return null; return animModel.animationName; }
public static void HurtBasedOnHitData(GameEntityModel model, FixedFloat damagePercentage, List <GameEntityModel> hitterSubjects = null) { GameEntityController controller = model.Controller() as GameEntityController; if (controller.lastHurts.Count > 0) { HitData hitData = controller.lastHurts[0].hitData; HurtBasedOnFacingOptions(model, hitData.facingOptions, damagePercentage, hitterSubjects); } }
// ---------------------- // Ground and Wall checks public static bool IsGrounded(GameEntityModel model) { PhysicPointModel pointModel = GameEntityController.GetPointModel(model); if (pointModel == null) { return(false); } return(PhysicPointController.IsGrounded(pointModel)); }
// Apply a force on the physics velocity affector public static FixedFloat GetVerticalImpulse(GameEntityModel model) { PhysicPointModel pointModel = GameEntityController.GetPointModel(model); if (pointModel == null) { return(FixedFloat.Zero); } return(pointModel.velocityAffectors[PhysicPointModel.defaultVelocityAffectorName].Y); }
public static FixedFloat CollisionZForce(GameEntityModel model) { PhysicPointModel pointModel = GameEntityController.GetPointModel(model); if (pointModel == null) { return(FixedFloat.Zero); } return(FixedFloat.Abs(pointModel.collisionInpact.Z)); }
public static bool IsHittingFarWall(GameEntityModel model) { PhysicPointModel pointModel = GameEntityController.GetPointModel(model); if (pointModel == null) { return(false); } return(pointModel.collisionInpact.Z > 0); }
// Forces the animation of an anchored entity, so that it can't be messed with it's current animation events public static void SetAnchoredEntityAnimation(GameEntityModel model, int anchorId, string animationName){ if (model.anchoredEntities == null || model.anchoredEntities.Count <= anchorId) return; GameEntityModel anchoredEntityModel = StateManager.state.GetModel(model.anchoredEntities[anchorId]) as GameEntityModel; if (anchoredEntityModel != null){ AnimationModel anchoredAnimationModel = GameEntityController.GetAnimationModel(anchoredEntityModel); AnimationController anchoredAnimController = anchoredAnimationModel.Controller() as AnimationController; if (anchoredAnimController != null){ // Force animation, so that it ignores any desired transition from a previous animation update anchoredAnimController.ForceAnimation(anchoredAnimationModel, animationName); } } }
// 7: GetColliding private static EventSubject <GameEntityModel> .GetSubjectsDelegate GetColliding(Storage.GenericParameter parameter) { int subjectId = parameter.SafeInt(0); return(DefaultDelegation(subjectId, delegate(GameEntityModel model, List <GameEntityModel> subjects){ GameEntityController controller = model.Controller() as GameEntityController; if (controller.lastCollisionEntityId != null && controller.lastCollisionEntityId != ModelReference.InvalidModelIndex) { GameEntityModel collidingEntity = StateManager.state.GetModel(controller.lastCollisionEntityId) as GameEntityModel; subjects.Add(collidingEntity); } })); }
// Safelly set position relative to self (e.g. vault), taking physics collisions in consideration public static void MoveEntity(GameEntityModel model, FixedVector3 relativePosition) { PhysicPointModel pointModel = GameEntityController.GetPointModel(model); if (pointModel != null) { PhysicPointController pointController = pointModel.Controller() as PhysicPointController; if (pointController != null) { pointController.SetVelocityAffector(pointModel, PhysicPointController.setPositionffectorName, relativePosition); } } }
// Anchor a model to it, and optionally move the parent relative to the entity being anchored (e.g. move back a little when grabbing) public static void AnchorEntity(GameEntityModel model, GameEntityModel modelToBeAnchored, int anchorId, FixedVector3 deltaPosRelativeToAnched){ AnchorEntity(model, modelToBeAnchored, anchorId); PhysicPointModel pointModel = GameEntityController.GetPointModel(model); PhysicPointModel anchoredPointModel = GameEntityController.GetPointModel(modelToBeAnchored); if (pointModel != null && anchoredPointModel != null){ PhysicPointController pointController = pointModel.Controller() as PhysicPointController; if (pointController != null){ if (!model.IsFacingRight()) deltaPosRelativeToAnched.X *= -1; FixedVector3 deltaPos = (anchoredPointModel.position + deltaPosRelativeToAnched) - pointModel.position; pointController.SetVelocityAffector(pointModel, PhysicPointController.setPositionffectorName, deltaPos); } } }
// Generic entity-entity collision with team check public static bool IsCollidingWithTeam(GameEntityModel model, InclusionType teamInclusionType, int teamId) { GameEntityController controller = model.Controller() as GameEntityController; if (controller.lastCollisionEntityId == ModelReference.InvalidModelIndex) { return(false); } bool isValid; InclusionCheck(teamInclusionType, WorldUtils.GetEntityTeam(controller.lastCollisionEntityId), teamId, out isValid); return(isValid); }
public static bool HurtContainsType(GameEntityModel model, HitData.HitType type) { GameEntityController controller = model.Controller() as GameEntityController; foreach (HitInformation info in controller.lastHurts) { if (info.hitData.type == type) { return(true); } } return(false); }
// Hurt at a certain collisionID public static bool HurtsContainCollisionId(GameEntityModel model, int collisionId) { GameEntityController controller = model.Controller() as GameEntityController; foreach (HitInformation hitInformation in controller.lastHurts) { if (hitInformation.collisionId == collisionId) { return(true); } } return(false); }
// Set the velocity affector bound to animation velocity control public static void SetAnimationVelocity(GameEntityModel model, FixedVector3 velocity) { PhysicPointModel pointModel = GameEntityController.GetPointModel(model); if (pointModel == null) { return; } if (!model.IsFacingRight()) { velocity.X *= -1; } pointModel.velocityAffectors[GameEntityController.animVelocityAffector] = velocity; }
// Reset X and Z force components on the physics velocity affector public static void ResetPlanarImpulse(GameEntityModel model) { PhysicPointModel pointModel = GameEntityController.GetPointModel(model); if (pointModel == null) { return; } FixedVector3 originalImpulse; pointModel.velocityAffectors.TryGetValue(PhysicPointModel.defaultVelocityAffectorName, out originalImpulse); pointModel.velocityAffectors[PhysicPointModel.defaultVelocityAffectorName] = new FixedVector3(0, originalImpulse.Y, 0) ; }
public static void SpawnAtHurtIntersection(GameEntityModel model, string prefabName, int lifetime, FixedVector3 offset, bool localSpace, ConvertGameToViewCoordinates gameToViewCoordinates) { // No visual spawns if state is being remade if (StateManager.Instance.IsRewindingState) { return; } GameEntityController controller = model.Controller() as GameEntityController; if (controller.lastHurts.Count == 0) { return; } SpawnAtIntersection(controller.lastHurts, model, prefabName, lifetime, offset, localSpace, gameToViewCoordinates); }
// Face to same direction as hitter is facing public static void FaceToHitterDirection(GameEntityModel model, bool oppositeFacing) { GameEntityController controller = model.Controller() as GameEntityController; PhysicPointModel pointModel = GameEntityController.GetPointModel(model); if (pointModel != null && controller.lastHurts.Count > 0) { HitInformation info = controller.lastHurts[0]; GameEntityModel hitter = StateManager.state.GetModel(info.entityId) as GameEntityModel; model.mIsFacingRight = hitter.IsFacingRight(); if (oppositeFacing) { model.mIsFacingRight = !model.IsFacingRight(); } } }
private static EventAction <GameEntityModel> .ExecutionDelegate BuildPausePhysics(Storage.GenericParameter parameter) { int numeratorSubjectId = parameter.SafeInt(1); string numeratorVariableName = parameter.SafeString(0); int defaultValue = parameter.SafeInt(2); FixedFloat percentage = (numeratorSubjectId == 0 || defaultValue == 0) ? 1 : ((FixedFloat)defaultValue) / 100; return(delegate(GameEntityModel model, List <GameEntityModel>[] subjectModels){ int numeratorValue = GetNumeratorValue(model, numeratorSubjectId, numeratorVariableName, defaultValue, subjectModels); int pauseValue = (int)(numeratorValue * percentage); if (pauseValue > 0) { GameEntityController.PausePhysics(model, pauseValue); } }); }
// Apply a force on the physics velocity affector public static void AddImpulse(GameEntityModel model, FixedVector3 impulse) { PhysicPointModel pointModel = GameEntityController.GetPointModel(model); if (pointModel == null) { return; } if (!model.IsFacingRight()) { impulse.X *= -1; } pointModel.velocityAffectors[PhysicPointModel.defaultVelocityAffectorName] += impulse; // pointModel.velocityAffectors[PhysicPointModel.defaultVelocityAffectorName] += new FixedVector3(0, impulse.Y, 0); // pointModel.velocityAffectors[GameEntityController.animVelocityAffector] += new FixedVector3(impulse.X, 0, impulse.Z); }