// Update is called once per frame
    void Update()
    {
        w = g.w;

        Ray        ray = cam.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        float distance = 100;

        if (Physics.Raycast(ray, out hit, 1000, default_layer))
        {
            distance = hit.distance;

            if (Input.GetMouseButton(0))
            {
                if (pHitPoint != null)
                {
                    // Camera movement
                    float y = transform.position.y;
                    transform.position += (pHitPoint - hit.point) / 2f;
                    transform.position  = new Vector3(transform.position.x, y, transform.position.z);
                }
            }

            pHitPoint = hit.point;

            {
                int x = Mathf.FloorToInt(hit.point.x);
                int z = Mathf.FloorToInt(hit.point.z);

                var result = tile.Requirements.ValidateTerrain(w, x, z);

                if (result.Valid)
                {
                    renderer.ChangeMaterial(trueMaterial);

                    if (Input.GetMouseButton(2))
                    {
                        w.BuildTile(x, z, tile);
                    }
                }
                else
                {
                    renderer.ChangeMaterial(falseMaterial);
                }

                selection_graphic.transform.position = new Vector3(
                    Mathf.Floor(hit.point.x),
                    Mathf.Floor(hit.point.y) + 0.1f + result.Location,
                    Mathf.Floor(hit.point.z));
            }
        }

        Debug.DrawRay(transform.position, ray.direction * distance, Color.white);
    }