public override void PostDraw()
        {
            Material avatar = null;
            Vector3  vector;

            Designator_AndroidToControl desi = null;
            bool isConnected = (csm != null && csm.connected);

            if (Find.DesignatorManager.SelectedDesignator is Designator_AndroidToControl)
            {
                desi = (Designator_AndroidToControl)Find.DesignatorManager.SelectedDesignator;
            }

            if (desi != null && desi.fromSkyCloud)
            {
                avatar = Tex.SelectableSX;
            }

            if (isConnected)
            {
                if (controller != null)
                {
                    avatar = Tex.RemotelyControlledNode;
                }
            }

            if (avatar != null)
            {
                vector    = this.parent.TrueCenter();
                vector.y  = Altitudes.AltitudeFor(AltitudeLayer.MetaOverlays) + 0.28125f;
                vector.z += 1.4f;
                vector.x += this.parent.def.size.x / 2;

                Graphics.DrawMesh(MeshPool.plane08, vector, Quaternion.identity, avatar, 0);
            }
        }
        public override IEnumerable <Gizmo> CompGetGizmosExtra()
        {
            Building build = (Building)parent;

            //Si aucun mind stocké
            if (storedMinds.Count() == 0 || !build.TryGetComp <CompPowerTrader>().PowerOn || !Booted())
            {
                yield break;
            }

            yield return(new Command_Action {
                icon = Tex.processInfo,
                defaultLabel = "ATPP_ProcessInfo".Translate(),
                defaultDesc = "ATPP_ProcessInfoDesc".Translate(),
                action = delegate() {
                    showFloatMenuMindsStored(delegate(Pawn p) {
                        Find.WindowStack.Add(new Dialog_InfoCard(p));
                    }, false, false, false, true);
                }
            });

            yield return(new Command_Action {
                icon = Tex.processRemove,
                defaultLabel = "ATPP_ProcessRemove".Translate(),
                defaultDesc = "ATPP_ProcessRemoveDesc".Translate(),
                action = delegate() {
                    showFloatMenuMindsStored(delegate(Pawn p) {
                        Find.WindowStack.Add(new Dialog_Msg("ATPP_ProcessRemove".Translate(), "ATPP_ProcessRemoveDescConfirm".Translate(p.LabelShortCap, getName()), delegate {
                            stopMindActivities(p);

                            RemoveMind(p);
                            p.Kill(null, null);

                            Messages.Message("ATPP_ProcessRemoveOK".Translate(p.LabelShortCap), parent, MessageTypeDefOf.PositiveEvent);

                            Utils.playVocal("soundDefSkyCloudMindDeletionCompleted");
                        }, false));
                    }, false, false, false, false);
                }
            });

            yield return(new Command_Action {
                icon = Tex.processDuplicate,
                defaultLabel = "ATPP_ProcessDuplicate".Translate(),
                defaultDesc = "ATPP_ProcessDuplicateDesc".Translate(),
                action = delegate() {
                    showFloatMenuMindsStored(delegate(Pawn p) {
                        CompSurrogateOwner cso = p.ATCompSurrogateOwner;
                        if (cso == null)
                        {
                            return;
                        }

                        int GT = Find.TickManager.TicksGame;

                        cso.replicationStartGT = GT;
                        cso.replicationEndingGT = GT + (Settings.mindReplicationHours * 2500);

                        replicatingMinds.Add(p);
                        stopMindActivities(p);

                        Messages.Message("ATPP_ProcessDuplicateOK".Translate(p.LabelShortCap), parent, MessageTypeDefOf.PositiveEvent);
                    }, false, false, false, false);
                }
            });

            yield return(new Command_Action {
                icon = Tex.processAssist,
                defaultLabel = "ATPP_ProcessAssist".Translate(),
                defaultDesc = "ATPP_ProcessAssistDesc".Translate(),
                action = delegate() {
                    List <FloatMenuOption> opts = new List <FloatMenuOption>();
                    //Affichage des minds affectés à l'assistement
                    opts.Add(new FloatMenuOption("ATPP_ProcessAssistAssignedMinds".Translate(), delegate {
                        List <FloatMenuOption> optsAdd = null;

                        //Check s'il y a lieu d'jaouter l'option (il y a au moin 1+ minds assigné à supprimer
                        if (assistingMinds.Count > 0)
                        {
                            optsAdd = new List <FloatMenuOption>();
                            optsAdd.Add(new FloatMenuOption("-" + ("ATPP_ProcessAssistUnassignAll".Translate()), delegate {
                                int nb = 0;
                                foreach (var m in storedMinds)
                                {
                                    if (assistingMinds.Contains(m))
                                    {
                                        assistingMinds.Remove(m);
                                        nb++;
                                    }
                                }

                                if (nb > 0)
                                {
                                    Messages.Message("ATPP_ProcessMassUnassist".Translate(nb), parent, MessageTypeDefOf.PositiveEvent);
                                }
                            }, MenuOptionPriority.Default, null, null, 0f, null, null));
                        }

                        showFloatMenuMindsStored(delegate(Pawn p) {
                            assistingMinds.Remove(p);

                            Messages.Message("ATPP_ProcessUnassistOK".Translate(p.LabelShortCap), parent, MessageTypeDefOf.PositiveEvent);
                        }, false, false, false, false, optsAdd, false, true);
                    }, MenuOptionPriority.Default, null, null, 0f, null, null));

                    //Affichage des minds non affectés à l'assistement
                    opts.Add(new FloatMenuOption("ATPP_ProcessAssistUnassignedMinds".Translate(), delegate {
                        List <FloatMenuOption> optsAdd = null;

                        //Check s'il y a lieu d'jaouter l'option (il y a des minds et des minds non ajoutés)
                        if (storedMinds.Count > 0 && getNbUnassistingMinds() > 0)
                        {
                            optsAdd = new List <FloatMenuOption>();
                            optsAdd.Add(new FloatMenuOption("-" + ("ATPP_ProcessAssistAssignAll".Translate()), delegate {
                                int nb = 0;
                                foreach (var m in storedMinds)
                                {
                                    if (!assistingMinds.Contains(m))
                                    {
                                        stopMindActivities(m);
                                        assistingMinds.Add(m);
                                        nb++;
                                    }
                                }

                                if (nb > 0)
                                {
                                    Messages.Message("ATPP_ProcessMassAssist".Translate(nb), parent, MessageTypeDefOf.PositiveEvent);
                                }
                            }, MenuOptionPriority.Default, null, null, 0f, null, null));
                        }

                        showFloatMenuMindsStored(delegate(Pawn p) {
                            stopMindActivities(p);
                            assistingMinds.Add(p);

                            Messages.Message("ATPP_ProcessAssistOK".Translate(p.LabelShortCap), parent, MessageTypeDefOf.PositiveEvent);
                        }, false, false, false, false, optsAdd, true);
                    }, MenuOptionPriority.Default, null, null, 0f, null, null));

                    FloatMenu floatMenuMap = new FloatMenu(opts);
                    Find.WindowStack.Add(floatMenuMap);
                }
            });

            yield return(new Command_Action {
                icon = Tex.processMigrate,
                defaultLabel = "ATPP_ProcessMigrate".Translate(),
                defaultDesc = "ATPP_ProcessMigrateDesc".Translate(),
                action = delegate() {
                    showFloatMenuMindsStored(delegate(Pawn p) {
                        Utils.ShowFloatMenuSkyCloudCores(delegate(Building core) {
                            CompSurrogateOwner cso = p.ATCompSurrogateOwner;
                            stopMindActivities(p);
                            cso.startMigration(core);
                        }, (Building)parent);
                    }, false, false, false, false);
                }
            });

            yield return(new Command_Action {
                icon = Tex.processSkillUp,
                defaultLabel = "ATPP_Skills".Translate(),
                defaultDesc = "ATPP_SkillsDesc".Translate(),
                action = delegate() {
                    showFloatMenuMindsStored(delegate(Pawn p) {
                        Find.WindowStack.Add(new Dialog_SkillUp(p, true));
                    }, false, false, false, true);
                }
            });

            yield return(new Command_Action {
                icon = Tex.AndroidToControlTarget,
                defaultLabel = "ATPP_AndroidToControlTarget".Translate(),
                defaultDesc = "ATPP_AndroidToControlTargetDesc".Translate(),
                action = delegate() {
                    showFloatMenuMindsStored(delegate(Pawn p) {
                        //Listing map de destination
                        List <FloatMenuOption> opts = new List <FloatMenuOption>();
                        string lib = "";
                        foreach (var m in Find.Maps)
                        {
                            if (m == Find.CurrentMap)
                            {
                                lib = "ATPP_ThisCurrentMap".Translate(m.Parent.Label);
                            }
                            else
                            {
                                lib = m.Parent.Label;
                            }

                            opts.Add(new FloatMenuOption(lib, delegate {
                                Current.Game.CurrentMap = m;
                                Designator_AndroidToControl x = new Designator_AndroidToControl(p, true);
                                Find.DesignatorManager.Select(x);
                            }, MenuOptionPriority.Default, null, null, 0f, null, null));
                        }
                        if (opts.Count != 0)
                        {
                            if (opts.Count == 1)
                            {
                                Designator_AndroidToControl x = new Designator_AndroidToControl(p, true);
                                Find.DesignatorManager.Select(x);
                            }
                            else
                            {
                                FloatMenu floatMenuMap = new FloatMenu(opts);
                                Find.WindowStack.Add(floatMenuMap);
                            }
                        }
                    }, true, true, false, false, null, true);
                }
            });

            if (Utils.isThereNotControlledSurrogateInCaravan())
            {
                //Si drones SX no controllés dans une caravane
                yield return(new Command_Action {
                    icon = Tex.AndroidToControlTargetRecovery,
                    defaultLabel = "ATPP_AndroidToControlTargetRecoverCaravan".Translate(),
                    defaultDesc = "ATPP_AndroidToControlTargetRecoverCaravanDesc".Translate(),
                    action = delegate() {
                        showFloatMenuMindsStored(delegate(Pawn p) {
                            Utils.ShowFloatMenuNotCOntrolledSurrogateInCaravan(p, delegate(Pawn sSX) {
                                CompSurrogateOwner cso = p.ATCompSurrogateOwner;
                                if (cso == null)
                                {
                                    return;
                                }

                                if (!Utils.GCATPP.isConnectedToSkyMind(sSX))
                                {
                                    //Tentative connection au skymind
                                    if (!Utils.GCATPP.connectUser(sSX))
                                    {
                                        return;
                                    }
                                }
                                cso.setControlledSurrogate(sSX);
                            });
                        }, true, true, false, false, null, true);
                    }
                });
            }

            if (getNbMindsConnectedToSurrogate() != 0 || controlledTurrets.Count() != 0)
            {
                yield return(new Command_Action {
                    icon = Tex.AndroidToControlTargetDisconnect,
                    defaultLabel = "ATPP_AndroidToControlTargetDisconnect".Translate(),
                    defaultDesc = "ATPP_AndroidToControlTargetDisconnectDesc".Translate(),
                    action = delegate() {
                        List <FloatMenuOption> opts = new List <FloatMenuOption>();
                        opts.Add(new FloatMenuOption("ATPP_ProcessDisconnectAllSurrogates".Translate(), delegate {
                            disconnectAllSurrogates();
                            disconnectAllRemotelyControlledTurrets();
                            Utils.playVocal("soundDefSkyCloudAllMindDisconnected");
                        }, MenuOptionPriority.Default, null, null, 0f, null, null));

                        showFloatMenuMindsStored(delegate(Pawn p) {
                            CompSurrogateOwner cso = p.ATCompSurrogateOwner;
                            if (cso != null && cso.isThereSX())
                            {
                                cso.disconnectControlledSurrogate(null);
                            }
                            stopRemotelyControlledTurret(p);
                        }, false, false, true, false, opts);
                    }
                });
            }

            yield break;
        }