public static void drawSimpleSpiderGizmo(JunctionSimpleSpider junctionSimpleSpider, float size, Vector3 posAbs, Vector3 targetAbs)
 {
     UnityEditorUtils.cylinder(posAbs, MUtil.qToAxesXZ(junctionSimpleSpider.axisAbs, targetAbs), 1, 10, 0, 1 * size, 0.1f * size, 0.1f * size);
     UnityEditorUtils.cylinder(posAbs,
                               MUtil.qToAxesXZ(junctionSimpleSpider.secondaryAxisAbs, junctionSimpleSpider.axisAbs),
                               1, 10, 0, 1 * size * 0.3f, 0.1f * size * 0.5f, 0.1f * size * 0.5f);
 }
示例#2
0
        private void Update()
        {
            if (ttl == -1)
            {
                return;
            }

            localTime += Time.deltaTime;
            speed     += acceleration * Time.deltaTime;


//            angleSpeed += rotAccel * dt;
            Quaternion rot      = transform.rotation;
            Quaternion rotForce = MUtil.toAngleAxis(angleSpeed.length() * Time.deltaTime, angleSpeed.normalized);

            rot = rotForce * rot;

            transform.SetPositionAndRotation(transform.position + speed * Time.deltaTime, rot);

//            scale += scaleSpeed * Time.deltaTime;
//            if (scale <= 0) Destroy(gameObject);

//            transform.localScale = new Vector3(scale, scale, scale);
            if (localTime >= ttl)
            {
                Destroy(gameObject);
            }
        }
示例#3
0
 //This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only).
 public override void OnValidate()
 {
     MUtil.logEvent(this, "OnValidate");
     needsUpdate = true;
     if (!Application.isPlaying)
     {
         needsReset = true;
     }
 }
示例#4
0
 public void reset()
 {
     MUtil.logEvent(this, "reset");
     //if (body == null) return;
     needsReset = false;
     engine.reset(transform.position, transform.rotation);
     targetPos = transform.position;
     targetRot = transform.rotation;
 }
示例#5
0
    protected override bool DoesPassCriteria(Player player)
    {
        if (!MUtil.TryGetStat <STAT_Happy>(player.gameObject, out StatItem stat))
        {
            return(false);
        }

        return(stat.GetValue() > requiredAmount);
    }
        public override void updateData()
        {
            base.updateData();

            int newCount = transform.childCount;

            MUtil.madeCount(bonesDeltaPos, newCount);
            MUtil.madeCount(bonesDeltaRot, newCount);
            MUtil.madeCount(stepNumbers, newCount);
        }
示例#7
0
 private void updateBones()
 {
     MUtil.madeCount(bonesDeltaPos, bonesGeometry.Count);
     MUtil.madeCount(bonesDeltaRot, bonesGeometry.Count);
     for (int index = 0; index < bonesGeometry.Count; index++)
     {
         Bone bone = bones[index];
         bone.attachedGeometry = bonesGeometry[index];
         bone.deltaPos         = bonesDeltaPos[index];
         bone.deltaRot         = bonesDeltaRot[index];
     }
 }
        //TODO call when needed only
        public override void updateData()
        {
            MUtil.logEvent(this, "updateData");
            normalRel             = normalRel.normalized;
            rotationJoint.axisRel = normalRel;
            elbowJoint.radius1    = r1;
            elbowJoint.radius2    = r2;
            bones[0].r            = r1;
            bones[1].r            = r2;
            maxLen = (r1 + r2) * 0.99f;//*0.99 because elbow junction "sticks" when it is close to the limit

            base.updateData();
        }
示例#9
0
        public override void fixedTick(float dt)
        {
            base.fixedTick(dt);

            if (target == null)
            {
                if (transform.parent == null)
                {
                    targetPos = initialLocalPos;
                }
                else
                {
                    targetPos = transform.parent.TransformPoint(initialLocalPos);
                }
            }

            if (!Application.isPlaying)
            {
                return;
            }
            if (rotate)
            {
                Quaternion curRotAbs = transform.rotation;
                if (rb == null)
                {
                    Vector3 rotAccel = Stepper5.torqueFromQuaternions(rotationMotor, curRotAbs, targetRot, angleSpeed, 1);
                    angleSpeed += rotAccel * dt;
                    Quaternion rotForce = MUtil.toAngleAxis(angleSpeed.length() * Time.deltaTime, angleSpeed.normalized);
                    transform.rotation = rotForce * curRotAbs;
                }
                else
                {
                    rb.AddTorque(Stepper5.torqueFromQuaternions(rotationMotor, curRotAbs, targetRot, rb.angularVelocity, 1), ForceMode.Acceleration);
                }
            }

            if (move)
            {
                Vector3 curPosAbs = transform.position;
                if (rb == null)
                {
                    Vector3 accel = posMotor.getAccel(targetPos, curPosAbs, speed, 1);
                    speed += accel * dt;
                    transform.position = curPosAbs + speed * dt;
                }
                else
                {
                    rb.AddForce(posMotor.getAccel(targetPos, curPosAbs, rb.velocity, 1), ForceMode.Acceleration);
                }
            }
        }
示例#10
0
 public override void OnEnable()
 {
     base.OnEnable();
     MUtil.logEvent(this, "OnEnable");
     needsUpdate = true;
     if (body != null)
     {
         bodyRigid = body.GetComponent <Rigidbody>();
     }
     else
     {
         bodyRigid = GetComponent <Rigidbody>();
     }
 }
示例#11
0
        public void fillOrigins(Vector3 xA1, float ar, Quaternion fromRot, Vector3 xB1, float br, Quaternion toRot, List <Vector3> poss, List <Quaternion> rots)
        {
            Vector3 vA = fromRot.rotate(new Vector3(ar, 0, 0));
            Vector3 vB = toRot.rotate(new Vector3(-br, 0, 0));

            Vector3 xA2 = xA1 + vA;
            Vector3 xB2 = xB1 + vB;

            poss[0] = xA1;

            Vector3 Z = fromRot.rotate(new Vector3(0, 0, 1));
//            Vector3 Z = -vA.crossProduct(xB1 - xA1);
            Quaternion startRotDif = Quaternion.identity;
            Quaternion endRotDif   = Quaternion.identity;

            if (simpleOrientation)
            {
                rots[0] = MUtil.qToAxesXZ(vA, Z);
            }
            else
            {
                startRotDif = fromRot.rotSub(MUtil.qToAxesXZ(vA, Z));
                endRotDif   = toRot.rotSub(MUtil.qToAxesXZ(-vB, Z));
                rots[0]     = fromRot;
            }

            Vector3 lastPos = poss[0];

            for (int i = 1; i < poss.Count; i++)
            {
                float progress = (float)i / (poss.Count - 1);

                Vector3 bb         = xA2.mix(xB2, progress);
                Vector3 currentPos = xA1.mix(bb, progress).mix(bb.mix(xB1, progress), progress);
                poss[i] = currentPos;
                rots[i] = MUtil.qToAxesXZ(currentPos - lastPos, Z);
                if (!simpleOrientation)
                {
                    rots[i] = rots[i] * startRotDif.nlerp(endRotDif, progress);
                }

                lastPos = currentPos;
            }
            if (!simpleOrientation)
            {
                rots[rots.Count - 1] = toRot;
            }
        }
示例#12
0
        public override void updateData()
        {
            MUtil.logEvent(this, "updateData");

//            rotJoint.axisRel = axis;
            rotJoint.axisRel          = rotJoint.axisRel.normalized;
            rotJoint.secondaryAxisRel = rotJoint.secondaryAxisRel.normalized;
            elbowJoint.radius1        = r1;
            elbowJoint.radius2        = r2;
            bones[0].r = r1;
            bones[1].r = r2;
            bones[2].r = footPlatformHeight;
            minLen     = Math.Abs(r1 - r2) * 1.1f;
            maxLen     = r1 + r2;


            base.updateData();
        }
//        [DrawGizmo(GizmoType.InSelectionHierarchy | GizmoType.Active)]
//        [DrawGizmo(GizmoType.InSelectionHierarchy | GizmoType.NonSelected | GizmoType.Active)]
        public static void OnDrawGizmos(MoveenSkelWithBones component)
        {
            if (!component.isActiveAndEnabled)
            {
                return;
            }
            Gizmos.color = BONE_COLOR;
            for (int i = 0; i < component.bones.Count; i++)
            {
                Bone bone = component.bones[i];
                bone.origin.tick(); //TODO ensure tick in root
                if (bone.origin.getRot().magnitude() < 0.3f)
                {
                    MUtil.log(component, "wrong quaternion: " + bone.origin.getRot());
                    //Debug.Log("  " + i);
                    continue;
                }
                UnityEditorUtils.diamond(bone.origin.getPos(), bone.origin.getRot().normalized(), bone.r);
            }

            Type type = component.GetType();

            Gizmos.color = Color.green;
            for (int index = 0; index < type.GetFields().Length; index++)
            {
                FieldInfo field = type.GetFields()[index];
                if (field.FieldType == typeof(Vector3))
                {
                    if (field.GetCustomAttributes(typeof(CustomSkelResultAttribute), true).Length != 0)
                    {
                        Vector3 cur = (Vector3)field.GetValue(component);
                        Gizmos.DrawWireSphere(cur, 0.04f);
                    }
                }
                if (field.FieldType == typeof(P <Vector3>))
                {
                    if (field.GetCustomAttributes(typeof(CustomSkelResultAttribute), true).Length != 0)
                    {
                        P <Vector3> cur = (P <Vector3>)field.GetValue(component);
                        Gizmos.DrawWireSphere(cur.v, 0.04f);
                    }
                }
            }
        }
示例#14
0
 public virtual void reset(Vector3 pos, Quaternion rot)
 {
     MUtil.logEvent(this, ("reset " + pos));
     this.comfortRadius = ((this.maxLen * 0.5f) * this.comfortRadiusRatio);
     this.bodyPos       = pos;
     this.bodyRot       = rot;
     this.bestTargetConservativeUnprojAbs = (Step2.toAbs(this.comfortPosRel, this.bodyPos, rot) + this.additionalDisplacement);
     this.bestTargetConservativeAbs       = this.bestTargetConservativeUnprojAbs;
     this.bestTargetProgressiveAbs        = this.bestTargetConservativeUnprojAbs;
     this.posAbs          = this.bestTargetConservativeUnprojAbs;
     this.oldPosAbs       = this.bestTargetConservativeUnprojAbs;
     this.speedAbs        = new Vector3();
     this.acceleration    = new Vector3();
     this.undockPauseCur  = 0;
     this.airTime         = 0;
     this.undockProgress  = 100500;
     this.undockCurTime   = 100500;
     this.footOrientation = rot;
 }
示例#15
0
        //This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only).
        public override void OnValidate()
        {
            MUtil.logEvent(this, "OnValidate");
            base.OnValidate();
            int targetBonesCount = bones.Count;

            if (bonesGeometry.Count != targetBonesCount)
            {
                Debug.LogWarning("Don't change array size!");
                if (bonesGeometry.Count > targetBonesCount)
                {
                    bonesGeometry.RemoveRange(targetBonesCount, bonesGeometry.Count - targetBonesCount);
                }
                while (bonesGeometry.Count < targetBonesCount)
                {
                    bonesGeometry.Add(null);
                }
            }
            needsUpdate = true;
        }
示例#16
0
        public override void tick(float dt)
        {
            if (target == null || body == null)
            {
                return;
            }
            Quaternion bestDirAbs = MUtil.qToAxes(target.position - transform.position, Vector3.up);
            Quaternion baseRotAbs = transform.parent.rotation * initialLocalRot;
            Quaternion difference = baseRotAbs.rotSub(bestDirAbs);

            differenceDegrees = MyMath.abs(MyMath.angleNormalizeSigned(MyMath.acos(difference.w) * 2)) * 180f / MyMath.PI;
            if (differenceDegrees > maxPrepareAngle)
            {
                bestDirAbs = baseRotAbs;                                     //look forward if the angle is more than maxPrepareAngle
            }
            else
            {
                bestDirAbs = Quaternion.RotateTowards(baseRotAbs, bestDirAbs, maxAngle); //try to look to the target, but not more than maxAngle
            }
            body.targetRot = bestDirAbs;
        }
示例#17
0
        public override void updateData()
        {
            MUtil.logEvent(this, "updateData");
            rotJoint.axisRel          = rotJoint.axisRel.normalized;
            rotJoint.secondaryAxisRel = rotJoint.secondaryAxisRel.normalized;

            //((SkelLeg2) legSkel).updateRadiuses(step.footPlatformHeight, rA + rC * style, rB + rC * (1 - style), rA, rB, rC);


            if (style)
            {
                r1 = rA + styleRatio * rB;
                r2 = maxLen - r1;
                visibleElbowJoint.radius1 = rB;
                visibleElbowJoint.radius2 = rC;
            }
            else
            {
                r2 = rC + styleRatio * rB;
                r1 = maxLen - r2;
                visibleElbowJoint.radius1 = rA;
                visibleElbowJoint.radius2 = rB;
            }

            maxLen = rA + rB + rC;
//            minLen = 0;
            minLen = Math.Abs(r1 - r2) * 1.1f;
//            minLen = Math.Max(rA, Math.Max(rB, Math.Max(rC, Math.Abs(r1 - r2))));


            invisibleElbowJoint.radius1 = r1;
            invisibleElbowJoint.radius2 = r2;

            bones[0].r = rA;
            bones[1].r = rB;
            bones[2].r = rC;
            bones[3].r = footPlatformHeight;

            base.updateData();
        }
        public static void draw2DLeg(Vector3 X, Vector3 Y, Vector3 pos, float size)
        {
//            Vector3 Z = X.crossProduct(Y);
//            X = Y.crossProduct(Z).normalized;
//                Gizmos.DrawLine(h.transform.position, h.transform.position + X * 0.2f + Y * 0.2f);
//                Gizmos.DrawLine(h.transform.position + X * 0.2f + Y * 0.2f, h.transform.position + X * 0.4f);
            Quaternion rot = MUtil.qToAxesXZ(X, Y);

            GL.PushMatrix();
            GL.LoadProjectionMatrix(Camera.current.projectionMatrix);

            GL.MultMatrix(Matrix4x4.TRS(
                              pos,
                              rot * Quaternion.AngleAxis(-45, Vector3.up), new Vector3(size, size, size)));
            diamond2d();
            GL.MultMatrix(Matrix4x4.TRS(
                              pos + rot.rotate(new Vector3(size * MyMath.cos(MyMath.PI / 4), 0, size * MyMath.cos(MyMath.PI / 4))),
                              rot * Quaternion.AngleAxis(45, Vector3.up), new Vector3(size, size, size)));
            diamond2d();

            GL.PopMatrix();
        }
示例#19
0
        private Quaternion getRotation()
        {
//            Debug.Log("getRotation: " + O.v + " " + X.v + " " + Y.v);
            if (forcedRotationEnabled)
            {
                return(forcedRotation);
            }

            if (xz)
            {
                x = xIsNormalizedRay ? X.v : (X.v - O.v).normalized;
                y = (yIsNormalizedRay ? Y.v : (Y.v - O.v).normalized).crossProduct(x);
                z = x.crossProduct(y);
            }
            else
            {
                x = xIsNormalizedRay ? X.v : (X.v - O.v).normalized;
                z = x.crossProduct(yIsNormalizedRay ? Y.v : (Y.v - O.v).normalized);
                y = z.crossProduct(x);
            }

            return(MUtil.qToAxes(x, y, z));
//            return MUtil.matrix2quaternion(x, y, z);
        }
示例#20
0
 public override void updateData()
 {
     base.updateData();
     MUtil.madeCount(poss, stepsCount + 2);
     MUtil.madeCount(rots, stepsCount + 2);
 }
示例#21
0
 public override StatItem GetStat(GameObject source)
 {
     return(MUtil.GetStat <STAT_Balance>(source));
 }
示例#22
0
        public void FixedUpdate()
        {
            if (!enabled)
            {
                return;
            }
            if (bodyRigid == null)
            {
                return;
            }

            if (Application.isPlaying)
            {
                calcUpByLegs();
            }

            //calc h
            float h           = 0;
            int   dockedCount = 0;

            for (int i = 0; i < moveen.engine.steps.Count; i++)
            {
                Step2 step = moveen.engine.steps[i];

                if (!step.dockedState)
                {
                    h += step.bestTargetProgressiveAbs.y; //to rise sharper
                }
                else
                {
                    dockedCount++;
                    h += step.posAbs.y;
                }
//                h += step.bestTargetProgressiveAbs.y;
            }
            float targetHeightMultiplier = jumpPreparing ? jumpPrepareHeightMul : jumpInProgress ? jumpTargetHeightMul : 1;

            h = moveen.engine.steps.Count == 0 ? height : (h / moveen.engine.steps.Count + height * targetHeightMultiplier);

            moveen.engine.horizontalMotor.maxSpeed = speed;

            if (jumpStrengthCurTime < jumpPrepareTime)
            {
                if (jumpStrengthCurTime > 0)
                {
                    //set only after space was released (jump started), as while space is pressed jumpStrengthCurTime is 0
                    moveen.engine.verticalMotor.copyFrom(jumpMotor);
                    jumpInProgress = true;
                }
                jumpStrengthCurTime += Time.deltaTime;
                //revert old value when jump is ended
                if (jumpStrengthCurTime >= jumpPrepareTime)
                {
                    moveen.engine.verticalMotor.copyFrom(previousVerticalMotor);
                    jumpInProgress = false;
                }
            }
            //remember value from editor when not jumping
            if (jumpStrengthCurTime >= jumpPrepareTime)
            {
                previousVerticalMotor.copyFrom(moveen.engine.verticalMotor);
            }


            Vector3 add = moveDir.normalized;

            add *= speed / moveen.engine.horizontalMotor.distanceToSpeed;
            add  = bodyRigid.transform.rotation.conjug().rotate(add); //global -> body local

            //limit forward, strafe, and rear speed
            if (add.x > 0)
            {
                add.x = Math.Min(add.x, speed);
            }
            if (add.x < 0)
            {
                add.x = Math.Max(add.x, -speed * rearSpeedMultiplyer);
            }
            if (add.z > 0)
            {
                add.z = Math.Min(add.z, speed * strafeSpeedMultiplyer);
            }
            if (add.z < 0)
            {
                add.z = Math.Max(add.z, -speed * strafeSpeedMultiplyer);
            }

            add = bodyRigid.transform.rotation.rotate(add); //body local -> global

            Vector3 newBestTargetPos = moveen.engine.imCenter.add(add).withSetY(h);

            if (quantCenter)
            {
                if (dockedCount == 0 || moveDir.length() > 0 || newBestTargetPos.dist(transform.position) > quantSize)
                {
                    transform.position = newBestTargetPos;
                }
            }
            else
            {
                transform.position = newBestTargetPos;
            }

            Quaternion rotForTarget;

            if (inclineBodyToLegs)
            {
                Vector3 wantedForward = chassisRot.rotate(Vector3.right);
                Vector3 wantedUp      = chassisRot.rotate(Vector3.up);
                Vector3 up            = wantedUp.mix(upByLegs, inclineBodyToLegsRatio);
                rotForTarget = MUtil.qToAxesYX(up, wantedForward);
            }
            else
            {
                rotForTarget = chassisRot;
            }

            if (dockedCount > 0)
            {
                //rotate target only if at least one leg is touching ground
                float      cosOfHalfAngle = (float)Math.Cos(bodyRotReactionSpeed / 2 / 180f * Math.PI); //TODO cache
                Quaternion rotDif         = rotForTarget.rotSub(transform.rotation);
                if (rotDif.w < 0)
                {
                    rotDif = rotDif.scale(-1);
                }
                if (rotDif.w < cosOfHalfAngle)
                {
                    rotDif = rotDif.normalizeWithFixedW(cosOfHalfAngle);
                }
                transform.rotation = transform.rotation * rotDif;
            }
            else
            {
                //get rotation from the body when in air
                //  because else - body could accumulate rotation it will be looking weird after grounding
                transform.rotation = moveen.targetRot;
            }

            moveen.targetPos = transform.position;
            moveen.targetRot = transform.rotation;
        }
示例#23
0
        public void FixedUpdate()
        {
            if (!enabled)
            {
                return;
            }
            if (bodyRigid == null)
            {
                return;
            }
            if (cam == null)
            {
                return;
            }
            bool grabInput = focusGrabber != null && focusGrabber.grab;

            if (Application.isPlaying)
            {
                calcUpByLegs();
            }

            float h           = 0;
            int   dockedCount = 0;

            for (int i = 0; i < moveen.engine.steps.Count; i++)
            {
                Step2 step = moveen.engine.steps[i];

//                if (!step.dockedState) { !!falls through on BM2 as best target can be -100500
//                    h += step.bestTargetProgressiveAbs.y; //to rise sharper
//                } else {
                dockedCount++;
                h += step.posAbs.y;
//                }
//                h += step.bestTargetProgressiveAbs.y;
            }
            float targetHeightMultiplier = jumpPreparing ? jumpPrepareHeightMul : jumpInProgress ? jumpTargetHeightMul : 1;

            h = moveen.engine.steps.Count == 0 ? height : (h / moveen.engine.steps.Count + height * targetHeightMultiplier);

            float maxSpeed = speed;

            if (Input.GetKey(KeyCode.LeftShift))
            {
                maxSpeed *= runSpeedMultiplier;
                moveen.engine.runJumpTime = runJumpTime;//it adds additional jump force on the step
            }
            else
            {
                moveen.engine.runJumpTime = 0;
            }
            moveen.engine.horizontalMotor.maxSpeed = maxSpeed;

            Vector3 add         = new Vector3();
            bool    movePressed = false;

            if (jumpStrengthCurTime < jumpPrepareTime)
            {
                if (jumpStrengthCurTime > 0)
                {
                    //set only after space was released (jump started), as while space is pressed jumpStrengthCurTime is 0
                    moveen.engine.verticalMotor.copyFrom(jumpMotor);
                    jumpInProgress = true;
                }
                jumpStrengthCurTime += Time.deltaTime;
                //revert old value when jump is ended
                if (jumpStrengthCurTime >= jumpPrepareTime)
                {
                    moveen.engine.verticalMotor.copyFrom(previousVerticalMotor);
                    jumpInProgress = false;
                }
            }
            //remember value from editor when not jumping
            if (jumpStrengthCurTime >= jumpPrepareTime)
            {
                previousVerticalMotor.copyFrom(moveen.engine.verticalMotor);
            }

            if (grabInput)
            {
                if (Input.GetKey(KeyCode.Space))
                {
                    jumpStrengthCurTime = 0;
                    jumpPreparing       = true;
                }
                else
                {
                    jumpPreparing = false;
                }
                if (Input.GetKey(KeyCode.W) || debugMoveForward)
                {
                    add        += new Vector3(1, 0, 0);
                    movePressed = true;
                }
                if (Input.GetKey(KeyCode.S))
                {
                    add        += new Vector3(-1, 0, 0);
                    movePressed = true;
                }
                if (Input.GetKey(KeyCode.A))
                {
                    add        += new Vector3(0, 0, 1);
                    movePressed = true;
                }
                if (Input.GetKey(KeyCode.D))
                {
                    add        += new Vector3(0, 0, -1);
                    movePressed = true;
                }
                add  = add.normalized();
                add *= (maxSpeed / moveen.engine.horizontalMotor.distanceToSpeed);

                //cam local
                add = MUtil.toAngleAxis(camYaw, new Vector3(0, 1, 0)).rotate(add); //cam local -> global
                add = bodyRigid.transform.rotation.conjug().rotate(add);           //global -> body local


                if (add.x > 0)
                {
                    add.x = Math.Min(add.x, maxSpeed);
                }
                if (add.x < 0)
                {
                    add.x = Math.Max(add.x, -maxSpeed * rearSpeedMultiplyer);
                }
                if (add.z > 0)
                {
                    add.z = Math.Min(add.z, maxSpeed * strafeSpeedMultiplyer);
                }
                if (add.z < 0)
                {
                    add.z = Math.Max(add.z, -maxSpeed * strafeSpeedMultiplyer);
                }


//            add = transform.rotation.rotate(add); //body local -> global
                add = bodyRigid.transform.rotation.rotate(add); //body local -> global
//            transform.position = body.transform.position + body.transform.rotation.rotate(add);
            }

            Vector3 newBestTargetPos = moveen.engine.imCenter.add(add).withSetY(h);

            if (quantCenter)
            {
                if (dockedCount == 0 || movePressed || newBestTargetPos.dist(transform.position) > quantSize)
                {
                    transform.position = newBestTargetPos;
                }
            }
            else
            {
                transform.position = newBestTargetPos;
            }

            wantedCamera = bodyRigid.position.withSetY(h);
//            wantedCamera = transform.position.limit(bodyRigid.position.withSetY(h), maxSpeed / 2).withSetY(h);//мерзко дрожит камера на больших скоростях

            if (grabInput)
            {
                float mx = Input.GetAxis("Mouse X") * 0.04f / Time.timeScale;
                float my = Input.GetAxis("Mouse Y") * -0.04f / Time.timeScale;
                camPitch = MyMath.clamp(camPitch + my, -1, 1);
                if (!debugFreezeRotation)
                {
                    camYaw = MyMath.angleNormalizeSigned(camYaw + mx); //comment to stop reacting on mouse
                }
                if (debugRotateRight)
                {
                    camYaw = MyMath.angleNormalizeSigned(camYaw + 0.3f * 0.05f); //uncomment to add constant rotation for test
                }
            }
            Quaternion yawRoll = MUtil.toAngleAxis(camYaw, new Vector3(0, 1, 0));

            Quaternion rotForCameraLook = yawRoll
                                          * MUtil.toAngleAxis((float)(Math.PI / 2), new Vector3(0, 1, 0))
                                          * MUtil.toAngleAxis(camPitch, new Vector3(1, 0, 0));
            Quaternion rotForCameraPos = yawRoll;
            Quaternion rotForTarget;


//            RaycastHit hit;
//            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//            Quaternion wantedRot = transform.rotation;
//            Vector3 hitPoint = new Vector3();
//
//            bool wasHit = false;
//            if (grabInput) {
//                wasHit = Physics.Raycast(ray.origin, ray.direction, out hit); //TODO cached
//                hitPoint = hit.point;
//                if (wasHit) {
//                    //lower target, because we are looking from the top, but the actor will be aiming from a side
//                    //  but we don't want correct height for walls and terrain
////                    if (hit.normal.y > 0.5f && hit.point.y > hit.collider.transform.position.y) {
////                        hitPoint.y = hit.collider.transform.position.y;
////                    }
//                    //Debug.DrawLine(new Vector3(-100, -100, -100), hitPoint, Color.red);
//
//                    if (moveen.engine.imCenter.dist(hitPoint) > 1) {
//                        wantedRot = MUtil.qToAxes(hitPoint - moveen.engine.imCenter, Vector3.up);
//                    }
//                } else {
//                    hitPoint = ray.origin + ray.direction * 40;
//                    wasHit = true;
//                }
//            }
//
//            yawRoll = Quaternion.FromToRotation(moveen.transform.rotation.rotate(Vector3.right), hitPoint.sub(moveen.transform.position));
//            rotForCameraPos = yawRoll;
//
//
//            //must be after this transform pos/rot change as target can be child of this
//            if (wasHit && aimTarget != null) aimTarget.position = hitPoint;



            if (inclineBodyToLegs)
            {
                rotForTarget = MUtil.qToAxesYX(Vector3.up.mix(upByLegs, inclineBodyToLegsRatio), yawRoll.rotate(new Vector3(1, 0, 0)));
//                rotForTarget = MUtil.qToAxes(yawRoll.rotate(new Vector3(1, 0, 0)), upByLegs);
            }
            else
            {
                rotForTarget = yawRoll * MUtil.toAngleAxis(camPitch * -0.5f, new Vector3(0, 0, 1));
            }


            if (grabInput)
            {
                cam.transform.rotation = rotForCameraLook;
                oldCam = oldCam.mix(wantedCamera, camApproachFactor);
                cam.transform.position = oldCam + rotForCameraPos.rotate(camPosition);
            }

//            float reactionSpeed = bodyRotReactionSpeed;
//            if (bodyRigid != null) reactionSpeed /= Math.Max(1, bodyRigid.velocity.length() * bodyRotReactionSpeedSpeed);

            if (dockedCount > 0)
            {
                //rotate target only if at least one leg is touching ground
                float      cosOfHalfAngle = (float)Math.Cos(bodyRotReactionSpeed / 2 / 180f * Math.PI); //TODO cache
                Quaternion rotDif         = rotForTarget.rotSub(transform.rotation);
                if (rotDif.w < 0)
                {
                    rotDif = rotDif.scale(-1);
                }
                if (rotDif.w < cosOfHalfAngle)
                {
                    rotDif = rotDif.normalizeWithFixedW(cosOfHalfAngle);
                }
                transform.rotation = transform.rotation * rotDif;
//                transform.rotation = rotForTarget;
            }
            else
            {
                //get rotation from the body when in air
                //  because else - body could accumulate rotation it will be looking weird after grounding
                transform.rotation = moveen.targetRot;
            }

            moveen.targetPos = transform.position;
            moveen.targetRot = transform.rotation;
        }
示例#24
0
 public override StatItem GetStat(GameObject source)
 {
     return(MUtil.GetStat <STAT_MoveSpeed>(source));
 }
示例#25
0
        public void FixedUpdate()
        {
            if (!enabled)
            {
                return;
            }
            if (bodyRigid == null)
            {
                return;
            }
            if (cam == null)
            {
                return;
            }

            bool grabInput = focusGrabber != null && focusGrabber.grab;

            if (Application.isPlaying)
            {
                calcUpByLegs();
            }

            float h           = 0;
            int   dockedCount = 0;

            for (int i = 0; i < moveen.engine.steps.Count; i++)
            {
                Step2 step = moveen.engine.steps[i];

                if (!step.dockedState)
                {
                    h += step.bestTargetProgressiveAbs.y; //to rise sharper
                }
                else
                {
                    dockedCount++;
                    h += step.posAbs.y;
                }
//                h += step.bestTargetProgressiveAbs.y;
            }
            float targetHeightMultiplier = jumpPreparing ? jumpPrepareHeightMul : jumpInProgress ? jumpTargetHeightMul : 1;

            h = moveen.engine.steps.Count == 0 ? height : (h / moveen.engine.steps.Count + height * targetHeightMultiplier);

            float maxSpeed = speed;

            if (Input.GetKey(KeyCode.LeftShift))
            {
                maxSpeed *= runSpeedMultiplier;
                moveen.engine.runJumpTime = runJumpTime;//it adds additional jump force on the step
            }
            else
            {
                moveen.engine.runJumpTime = 0;
            }
            moveen.engine.horizontalMotor.maxSpeed = maxSpeed;

            Vector3 add         = new Vector3();
            bool    movePressed = false;

            if (jumpStrengthCurTime < jumpPrepareTime)
            {
                if (jumpStrengthCurTime > 0)
                {
                    //set only after space was released (jump started), as while space is pressed jumpStrengthCurTime is 0
                    moveen.engine.verticalMotor.copyFrom(jumpMotor);
                    jumpInProgress = true;
                }
                jumpStrengthCurTime += Time.deltaTime;
                //revert old value when jump is ended
                if (jumpStrengthCurTime >= jumpPrepareTime)
                {
                    moveen.engine.verticalMotor.copyFrom(previousVerticalMotor);
                    jumpInProgress = false;
                }
            }
            //remember value from editor when not jumping
            if (jumpStrengthCurTime >= jumpPrepareTime)
            {
                previousVerticalMotor.copyFrom(moveen.engine.verticalMotor);
            }

            if (grabInput)
            {
                if (Input.GetKey(KeyCode.Space))
                {
                    jumpStrengthCurTime = 0;
                    jumpPreparing       = true;
                }
                else
                {
                    jumpPreparing = false;
                }
                Vector3 upDown    = localWasd ? new Vector3(1, 0, 0) : new Vector3(0, 0, 1);
                Vector3 leftRight = localWasd ? new Vector3(0, 0, 1) : new Vector3(-1, 0, 0);

                if (Input.GetKey(KeyCode.W) || debugMoveForward)
                {
                    add        += upDown;
                    movePressed = true;
                }
                if (Input.GetKey(KeyCode.S))
                {
                    add        -= upDown;
                    movePressed = true;
                }
                if (Input.GetKey(KeyCode.A))
                {
                    add        += leftRight;
                    movePressed = true;
                }
                if (Input.GetKey(KeyCode.D))
                {
                    add        -= leftRight;
                    movePressed = true;
                }
                add  = add.normalized();
                add *= maxSpeed / moveen.engine.horizontalMotor.distanceToSpeed;
                if (!localWasd)
                {
                    add = bodyRigid.transform.rotation.conjug().rotate(add); //global -> body local
                }

                //limit forward, strafe, and rear speed
                if (add.x > 0)
                {
                    add.x = Math.Min(add.x, maxSpeed);
                }
                if (add.x < 0)
                {
                    add.x = Math.Max(add.x, -maxSpeed * rearSpeedMultiplyer);
                }
                if (add.z > 0)
                {
                    add.z = Math.Min(add.z, maxSpeed * strafeSpeedMultiplyer);
                }
                if (add.z < 0)
                {
                    add.z = Math.Max(add.z, -maxSpeed * strafeSpeedMultiplyer);
                }

                add = bodyRigid.transform.rotation.rotate(add); //body local -> global
            }

            Vector3 newBestTargetPos = moveen.engine.imCenter.add(add).withSetY(h);

            if (quantCenter)
            {
                if (dockedCount == 0 || movePressed || newBestTargetPos.dist(transform.position) > quantSize)
                {
                    transform.position = newBestTargetPos;
                }
            }
            else
            {
                transform.position = newBestTargetPos;
            }

            wantedCamera = moveen.engine.imCenter.withSetY(h);


            RaycastHit hit;
            Ray        ray       = Camera.main.ScreenPointToRay(Input.mousePosition);
            Quaternion wantedRot = transform.rotation;
            Vector3    hitPoint  = new Vector3();

            bool wasHit = false;

            if (grabInput)
            {
                wasHit   = Physics.Raycast(ray.origin, ray.direction, out hit); //TODO cached
                hitPoint = hit.point;
                if (wasHit)
                {
                    //lower target, because we are looking from the top, but the actor will be aiming from a side
                    //  but we don't want correct height for walls and terrain
                    if (hit.normal.y > 0.5f && hit.point.y > hit.collider.transform.position.y)
                    {
                        hitPoint.y = hit.collider.transform.position.y;
                    }
                    //Debug.DrawLine(new Vector3(-100, -100, -100), hitPoint, Color.red);

                    if (moveen.engine.imCenter.dist(hitPoint) > 1)
                    {
                        wantedRot = MUtil.qToAxes(hitPoint - moveen.engine.imCenter, Vector3.up);
                    }
                }
            }

            oldCam = oldCam.mix(wantedCamera, camApproachFactor);
            if (grabInput)
            {
                cam.transform.position    = cam.transform.position.mix(oldCam + camPosition + wantedRot.rotate(new Vector3(maxSpeed * camAheadMul, 0, 0)), 0.1f);
                cam.transform.eulerAngles = camRotation;
            }
//            cam.transform.position = oldCam + camPosition + wantedRot.rotate(new Vector3(maxSpeed, 0, 0));

            if (dockedCount > 0)
            {
                //rotate target only if at least one leg is touching ground
                float      cosOfHalfAngle = (float)Math.Cos(bodyRotReactionSpeed / 2 / 180f * Math.PI); //TODO cache
                Quaternion rotDif         = wantedRot.rotSub(transform.rotation);
                if (rotDif.w < 0)
                {
                    rotDif = rotDif.scale(-1);
                }
                if (rotDif.w < cosOfHalfAngle)
                {
                    rotDif = rotDif.normalizeWithFixedW(cosOfHalfAngle);
                }
                transform.rotation = transform.rotation * rotDif;
            }
            else
            {
                //get rotation from the body when in air
                //  because else - body could accumulate rotation it will be looking weird after grounding
                transform.rotation = moveen.targetRot;
            }

            moveen.targetPos = transform.position;
            moveen.targetRot = transform.rotation;

            //must be after this transform pos/rot change as target can be child of this
            if (wasHit && aimTarget != null)
            {
                aimTarget.position = hitPoint;
            }
        }
 public void OnTransformChildrenChanged()
 {
     MUtil.logEvent(this, "OnTransformChildrenChanged");
     needsUpdate = true;
 }
示例#27
0
 public override void tick(float dt)
 {
     resultRot = MUtil.qToAxes(targetAbs.v - basisAbs.v, YAbs.v);
 }
示例#28
0
        public void FixedUpdate()
        {
            if (!enabled)
            {
                return;
            }
            if (bodyRigid == null)
            {
                return;
            }
            if (cam == null)
            {
                return;
            }
            bool grabInput = focusGrabber != null && focusGrabber.grab;

            if (Application.isPlaying)
            {
                calcUpByLegs();
            }

            float h           = 0;
            int   dockedCount = 0;

            for (int i = 0; i < moveen.engine.steps.Count; i++)
            {
                Step2 step = moveen.engine.steps[i];

                if (!step.dockedState)
                {
                    h += step.bestTargetProgressiveAbs.y; //to rise sharper
                }
                else
                {
                    dockedCount++;
                    h += step.posAbs.y;
                }
//                h += step.bestTargetProgressiveAbs.y;
            }
            float targetHeightMultiplier = jumpPreparing ? jumpPrepareHeightMul : jumpInProgress ? jumpTargetHeightMul : 1;

            h = moveen.engine.steps.Count == 0 ? height : (h / moveen.engine.steps.Count + height * targetHeightMultiplier);

            float maxSpeed = speed;

            if (Input.GetKey(KeyCode.LeftShift))
            {
                maxSpeed *= runSpeedMultiplier;
                moveen.engine.runJumpTime = runJumpTime;//it adds additional jump force on the step
            }
            else
            {
                moveen.engine.runJumpTime = 0;
            }
            moveen.engine.horizontalMotor.maxSpeed = maxSpeed;

            Vector3 add         = new Vector3();
            bool    movePressed = false;

            if (jumpStrengthCurTime < jumpPrepareTime)
            {
                if (jumpStrengthCurTime > 0)
                {
                    //set only after space was released (jump started), as while space is pressed jumpStrengthCurTime is 0
                    moveen.engine.verticalMotor.copyFrom(jumpMotor);
                    jumpInProgress = true;
                }
                jumpStrengthCurTime += Time.deltaTime;
                //revert old value when jump is ended
                if (jumpStrengthCurTime >= jumpPrepareTime)
                {
                    moveen.engine.verticalMotor.copyFrom(previousVerticalMotor);
                    jumpInProgress = false;
                }
            }
            //remember value from editor when not jumping
            if (jumpStrengthCurTime >= jumpPrepareTime)
            {
                previousVerticalMotor.copyFrom(moveen.engine.verticalMotor);
            }

            if (grabInput)
            {
                if (Input.GetKey(KeyCode.Space))
                {
                    jumpStrengthCurTime = 0;
                    jumpPreparing       = true;
                }
                else
                {
                    jumpPreparing = false;
                }
                if (Input.GetKey(KeyCode.W) || debugMoveForward)
                {
                    add        += new Vector3(1, 0, 0);
                    movePressed = true;
                }
                if (Input.GetKey(KeyCode.S))
                {
                    add        += new Vector3(-1, 0, 0);
                    movePressed = true;
                }
                if (Input.GetKey(KeyCode.A))
                {
                    add        += new Vector3(0, 0, 1);
                    movePressed = true;
                }
                if (Input.GetKey(KeyCode.D))
                {
                    add        += new Vector3(0, 0, -1);
                    movePressed = true;
                }
                add  = add.normalized();
                add *= (maxSpeed / moveen.engine.horizontalMotor.distanceToSpeed);

                //cam local
//                add = MUtil.toAngleAxis(camYaw, new Vector3(0, 1, 0)).rotate(add); //cam local -> global
//                add = bodyRigid.transform.rotation.conjug().rotate(add); //global -> body local


                if (add.x > 0)
                {
                    add.x = Math.Min(add.x, maxSpeed);
                }
                if (add.x < 0)
                {
                    add.x = Math.Max(add.x, -maxSpeed * rearSpeedMultiplyer);
                }
                if (add.z > 0)
                {
                    add.z = Math.Min(add.z, maxSpeed * strafeSpeedMultiplyer);
                }
                if (add.z < 0)
                {
                    add.z = Math.Max(add.z, -maxSpeed * strafeSpeedMultiplyer);
                }


//            add = transform.rotation.rotate(add); //body local -> global
                add = bodyRigid.transform.rotation.rotate(add); //body local -> global
//            transform.position = body.transform.position + body.transform.rotation.rotate(add);
            }

            Vector3 newBestTargetPos = moveen.engine.imCenter.add(add).withSetY(h);

            if (quantCenter)
            {
                if (dockedCount == 0 || movePressed || newBestTargetPos.dist(transform.position) > quantSize)
                {
                    transform.position = newBestTargetPos;
                }
            }
            else
            {
                transform.position = newBestTargetPos;
            }

            float leftRight = 0;

            if (grabInput)
            {
                float my = Input.GetAxis("Mouse Y") * -0.02f / Time.timeScale;

                leftRight = (Input.mousePosition.x / Screen.width - 0.5f) * 2;
                if (debugFreezeRotation)
                {
                    leftRight = 0;
                }
                if (debugRotateRight)
                {
                    leftRight = 0.5f;
                }

                if (leftRight > 0)
                {
                    leftRight = MyMath.smoothstep(0, 1, leftRight);
                }
                else
                {
                    leftRight = -MyMath.smoothstep(0, 1, -leftRight);
                }

                camPitch = MyMath.clamp(camPitch + my, -1, 1);
            }


//            RaycastHit hit;
//            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

//            Quaternion yawRoll = Quaternion.AngleAxis(leftRight * 10, Vector3.up) * transform.rotation;
            Quaternion yawRoll = Quaternion.AngleAxis(leftRight * 10, Vector3.up) * MUtil.qToAxesYX(Vector3.up, transform.rotation.rotate(Vector3.right));
//            Quaternion yawRoll = Quaternion.FromToRotation(moveen.engine.realBodyRot.rotate(Vector3.right), hitPoint.sub(moveen.transform.position));



            Quaternion rotForCameraPos = yawRoll * MUtil.toAngleAxis(-camPitch * 0.5f, new Vector3(0, 0, 1));
//            Quaternion rotForCameraLook = rotForCameraPos;
            Quaternion rotForCameraLook = yawRoll
                                          * MUtil.toAngleAxis((float)(Math.PI / 2), new Vector3(0, 1, 0))
                                          * MUtil.toAngleAxis(camPitch, new Vector3(1, 0, 0));



            Vector3 wantedDir = yawRoll.rotate(new Vector3(1, 0, 0));
//            if (wantedDir.scalarProduct(moveen.engine.inputWantedRot.rotate(Vector3.right)) > 0.95f) {
//                yawRoll = transform.rotation;
//                wantedDir = yawRoll.rotate(new Vector3(1, 0, 0));
//            }
            Quaternion rotForTarget;

            if (inclineBodyToLegs)
            {
                rotForTarget = MUtil.qToAxesYX(Vector3.up.mix(upByLegs, inclineBodyToLegsRatio), wantedDir);
//                rotForTarget = MUtil.qToAxes(yawRoll.rotate(new Vector3(1, 0, 0)), upByLegs);
            }
            else
            {
                rotForTarget = yawRoll * MUtil.toAngleAxis(camPitch * -0.5f, new Vector3(0, 0, 1));
            }


            if (grabInput)
            {
                Vector3 wantedCamera = moveen.engine.imCenter.withSetY(h);
                cam.transform.rotation = rotForCameraLook;
                oldCam = oldCam.mix(wantedCamera, camApproachFactor);
                cam.transform.position = oldCam + rotForCameraPos.rotate(camPosition);
            }

//            float reactionSpeed = bodyRotReactionSpeed;
//            if (bodyRigid != null) reactionSpeed /= Math.Max(1, bodyRigid.velocity.length() * bodyRotReactionSpeedSpeed);

            if (dockedCount > 0)
            {
                //rotate target only if at least one leg is touching ground
                float      cosOfHalfAngle = (float)Math.Cos(bodyRotReactionSpeed / 2 / 180f * Math.PI); //TODO cache
                Quaternion rotDif         = rotForTarget.rotSub(transform.rotation);
                if (rotDif.w < 0)
                {
                    rotDif = rotDif.scale(-1);
                }
                if (rotDif.w < cosOfHalfAngle)
                {
                    rotDif = rotDif.normalizeWithFixedW(cosOfHalfAngle);
                }
                transform.rotation = transform.rotation * rotDif;
//                transform.rotation = rotForTarget;
            }
            else
            {
                //get rotation from the body when in air
                //  because else - body could accumulate rotation it will be looking weird after grounding
                transform.rotation = moveen.targetRot;
            }

            moveen.targetPos = transform.position;
            moveen.targetRot = transform.rotation;


            //must be after this transform pos/rot change as target can be child of this
//            if (wasHit && aimTarget != null) aimTarget.position = hitPoint;
        }
示例#29
0
        private void Create()
        {
            if (!this.deposit.DBManager.DynamicProperties.SupportVM())
            {
                throw new ContractValidateException("vm work is off, need to be opened by the committee");
            }

            CreateSmartContract contract = ContractCapsule.GetSmartContractFromTransaction(this.transaction);

            if (contract == null)
            {
                throw new ContractValidateException("Cannot get CreateSmartContract from transaction");
            }

            SmartContract new_contract = contract.NewContract;

            if (!contract.OwnerAddress.Equals(new_contract.OriginAddress))
            {
                Logger.Info("OwnerAddress not equals OriginAddress");
                throw new VMIllegalException("OwnerAddress is not equals OriginAddress");
            }

            byte[] contract_name = Encoding.UTF8.GetBytes(new_contract.Name);

            if (contract_name.Length > VMParameter.CONTRACT_NAME_LENGTH)
            {
                throw new ContractValidateException("contractName's length cannot be greater than 32");
            }

            long percent = contract.NewContract.ConsumeUserResourcePercent;

            if (percent < 0 || percent > DefineParameter.ONE_HUNDRED)
            {
                throw new ContractValidateException("percent must be >= 0 and <= 100");
            }

            byte[] contract_address = Wallet.GenerateContractAddress(this.transaction);
            if (this.deposit.GetAccount(contract_address) != null)
            {
                throw new ContractValidateException(
                          "Trying to create a contract with existing contract address: " + Wallet.AddressToBase58(contract_address));
            }

            new_contract.ContractAddress = ByteString.CopyFrom(contract_address);

            long call_value  = new_contract.CallValue;
            long token_value = 0;
            long token_id    = 0;

            if (VMConfig.AllowTvmTransferTrc10)
            {
                token_value = contract.CallTokenValue;
                token_id    = contract.TokenId;
            }

            byte[] caller_address = contract.OwnerAddress.ToByteArray();
            try
            {
                long fee_limit = this.transaction.RawData.FeeLimit;
                if (fee_limit < 0 || fee_limit > VMConfig.MAX_FEE_LIMIT)
                {
                    Logger.Info(string.Format("invalid feeLimit {0}", fee_limit));
                    throw new ContractValidateException(
                              "feeLimit must be >= 0 and <= " + VMConfig.MAX_FEE_LIMIT);
                }

                AccountCapsule creator      = this.deposit.GetAccount(new_contract.OriginAddress.ToByteArray());
                long           energy_limit = 0;
                if (VMConfig.EnergyLimitHardFork)
                {
                    if (call_value < 0)
                    {
                        throw new ContractValidateException("callValue must >= 0");
                    }
                    if (token_value < 0)
                    {
                        throw new ContractValidateException("tokenValue must >= 0");
                    }
                    if (new_contract.OriginEnergyLimit <= 0)
                    {
                        throw new ContractValidateException("The originEnergyLimit must be > 0");
                    }
                    energy_limit = GetAccountEnergyLimitWithFixRatio(creator, fee_limit, call_value);
                }
                else
                {
                    energy_limit = GetAccountEnergyLimitWithFloatRatio(creator, fee_limit, call_value);
                }

                CheckTokenValueAndId(token_value, token_id);

                byte[] ops = new_contract.Bytecode.ToByteArray();
                this.root_internal_transaction = new InternalTransaction(this.transaction, this.transaction_type);

                long max_cpu_time_tx = this.deposit.DBManager.DynamicProperties.GetMaxCpuTimeOfOneTx() * DefineParameter.ONE_THOUSAND;
                long tx_cpu_limit    = (long)(max_cpu_time_tx * GetCpuLimitInUsRatio());
                long vm_start        = Helper.NanoTime() / DefineParameter.ONE_THOUSAND;
                long vm_should_end   = vm_start + tx_cpu_limit;

                IProgramInvoke invoke = this.invoke_factory.CreateProgramInvoke(TransactionType.TX_CONTRACT_CREATION_TYPE,
                                                                                this.executor_type,
                                                                                this.transaction,
                                                                                token_value,
                                                                                token_id,
                                                                                this.block.Instance,
                                                                                this.deposit,
                                                                                vm_start,
                                                                                vm_should_end,
                                                                                energy_limit);

                this.vm      = new Vm();
                this.program = new Program(ops, invoke, this.root_internal_transaction, this.block);
                byte[] tx_id = new TransactionCapsule(this.transaction).Id.Hash;
                this.program.RootTransactionId = tx_id;

                // TODO: EventPluginLoader is not Implementation
                //if (this.enable_listener
                //    && (EventPluginLoader.getInstance().isContractEventTriggerEnable()
                //    || EventPluginLoader.getInstance().isContractLogTriggerEnable())
                //    && IsCheckTransaction)
                //{
                //    logInfoTriggerParser = new LogInfoTriggerParser(this.block.getNum(), this.block.getTimeStamp(), txId, callerAddress);
                //}
            }
            catch (Exception e)
            {
                Logger.Info(e.Message);
                throw new ContractValidateException(e.Message);
            }
            this.program.Result.ContractAddress = contract_address;
            this.deposit.CreateAccount(contract_address, new_contract.Name, AccountType.Contract);
            this.deposit.CreateContract(contract_address, new ContractCapsule(new_contract));
            byte[] code = new_contract.Bytecode.ToByteArray();

            if (!VMConfig.AllowTvmConstantinople)
            {
                deposit.SaveCode(contract_address, ProgramPrecompile.GetCode(code));
            }

            if (call_value > 0)
            {
                MUtil.Transfer(this.deposit, caller_address, contract_address, call_value);
            }
            if (VMConfig.AllowTvmTransferTrc10)
            {
                if (token_value > 0)
                {
                    MUtil.TransferToken(this.deposit, caller_address, contract_address, token_id.ToString(), token_value);
                }
            }
        }
示例#30
0
        private void Call()
        {
            if (!this.deposit.DBManager.DynamicProperties.SupportVM())
            {
                Logger.Info("vm work is off, need to be opened by the committee");
                throw new ContractValidateException("VM work is off, need to be opened by the committee");
            }

            TriggerSmartContract contract = ContractCapsule.GetTriggerContractFromTransaction(this.transaction);

            if (contract == null)
            {
                return;
            }

            if (contract.ContractAddress == null)
            {
                throw new ContractValidateException("Cannot get contract address from TriggerContract");
            }

            byte[] contract_address = contract.ContractAddress.ToByteArray();

            ContractCapsule deployed_contract = this.deposit.GetContract(contract_address);

            if (null == deployed_contract)
            {
                Logger.Info("No contract or not a smart contract");
                throw new ContractValidateException("No contract or not a smart contract");
            }

            long call_value  = contract.CallValue;
            long token_value = 0;
            long token_id    = 0;

            if (VMConfig.AllowTvmTransferTrc10)
            {
                token_value = contract.CallTokenValue;
                token_id    = contract.TokenId;
            }

            if (VMConfig.EnergyLimitHardFork)
            {
                if (call_value < 0)
                {
                    throw new ContractValidateException("callValue must >= 0");
                }
                if (token_value < 0)
                {
                    throw new ContractValidateException("tokenValue must >= 0");
                }
            }

            byte[] caller_address = contract.OwnerAddress.ToByteArray();
            CheckTokenValueAndId(token_value, token_id);

            byte[] code = this.deposit.GetCode(contract_address);
            if (code != null && code.Length > 0)
            {
                long fee_limit = this.transaction.RawData.FeeLimit;
                if (fee_limit < 0 || fee_limit > VMConfig.MAX_FEE_LIMIT)
                {
                    Logger.Info(string.Format("invalid feeLimit {0}", fee_limit));
                    throw new ContractValidateException(
                              "feeLimit must be >= 0 and <= " + VMConfig.MAX_FEE_LIMIT);
                }

                AccountCapsule caller       = this.deposit.GetAccount(caller_address);
                long           energy_limit = 0;
                if (this.is_static_call)
                {
                    energy_limit = DefineParameter.ENERGY_LIMIT_IN_CONSTANT_TX;
                }
                else
                {
                    AccountCapsule creator = this.deposit.GetAccount(deployed_contract.Instance.OriginAddress.ToByteArray());
                    energy_limit = GetTotalEnergyLimit(creator, caller, contract, fee_limit, call_value);
                }

                long max_cpu_time_tx = this.deposit.DBManager.DynamicProperties.GetMaxCpuTimeOfOneTx() * DefineParameter.ONE_THOUSAND;
                long tx_cpu_limit    =
                    (long)(max_cpu_time_tx * GetCpuLimitInUsRatio());
                long           vm_start      = Helper.NanoTime() / DefineParameter.ONE_THOUSAND;
                long           vm_should_end = vm_start + tx_cpu_limit;
                IProgramInvoke invoke        = this.invoke_factory.CreateProgramInvoke(TransactionType.TX_CONTRACT_CALL_TYPE,
                                                                                       this.executor_type,
                                                                                       this.transaction,
                                                                                       token_value,
                                                                                       token_id,
                                                                                       this.block.Instance,
                                                                                       this.deposit,
                                                                                       vm_start,
                                                                                       vm_should_end,
                                                                                       energy_limit);

                if (this.is_static_call)
                {
                    invoke.IsStaticCall = true;
                }

                this.vm = new Vm();
                this.root_internal_transaction = new InternalTransaction(this.transaction, this.transaction_type);
                this.program = new Program(code, invoke, this.root_internal_transaction, this.block);
                byte[] tx_id = new TransactionCapsule(this.transaction).Id.Hash;
                this.program.RootTransactionId = tx_id;

                // // TODO: EventPluginLoader is not Implementation
                //if (enableEventLinstener &&
                //    (EventPluginLoader.getInstance().isContractEventTriggerEnable()
                //        || EventPluginLoader.getInstance().isContractLogTriggerEnable())
                //    && isCheckTransaction())
                //{
                //    logInfoTriggerParser = new LogInfoTriggerParser(this.block.getNum(), this.block.getTimeStamp(), txId, callerAddress);
                //}
            }

            this.program.Result.ContractAddress = contract_address;
            if (call_value > 0)
            {
                MUtil.Transfer(this.deposit, caller_address, contract_address, call_value);
            }

            if (VMConfig.AllowTvmTransferTrc10)
            {
                if (token_value > 0)
                {
                    MUtil.TransferToken(this.deposit, caller_address, contract_address, token_id.ToString(), token_value);
                }
            }
        }