Tú eliges Capital SimCity Capital Sims Capital Spore
Capital SimCity

[Tutorial] CiSk - C# Modding: 002 - Investigando.

Subforo dedicado para publicar los mods más destacados creados por la comunidad.

Moderador: Equipo moderador [CSC]

[Tutorial] CiSk - C# Modding: 002 - Investigando.

Notapor wyllman » 25 Jul 2015, 11:21

2. Investigando. Desbloquear calles básicas.

Volviendo al tema de la escasa documentación sobre las librerías del juego, de la que disponemos. En este capítulo, vamos a explorar el proceso de investigación de una librería “.dll” y cómo empezar a buscarnos la vida para aprender a modificar el juego.

El objetivo de la modificación de ejemplo que se va a desarrollar en este tutorial es que cuando se inicie un mapa nuevo, estén desbloqueadas las calles básicas de doble sentido y las calles básicas de sentido único. Actualmente, en el juego hasta que no construyes, al menos una calle básica de doble sentido, no se desbloquea la construcción de la calle básica de sentido único.

Para esta tarea tenemos varias opciones, la más común es buscar en la documentación pertinente de las librerías del juego. Esto lo vamos a ver con más detalle en próximas secciones, así que vamos a considerar que no encontramos nada en la documentación que nos ayude en nuestra tarea.

Otra forma es, descompilar las propias librerías del juego y, con mucha paciencia, recorrer todas las clases y funciones que contenga hasta dar con algo interesante. En próximos capítulos intentaremos analizar cada una de las librerías del juego para ver sus funcionalidades.

Por fin, para el caso que nos ocupa vamos a buscar en foros y modificaciones hechas por otros a ver qué encontramos. Y resulta que ya hay una modificación hecha que realiza la tarea que queremos. Como el objetivo es aprender, vamos a usar dicha modificación, la vamos a descompilar y vamos a hacer nuestro ejemplo copiandonos, pero intentando entender qué está sucediendo.

2.1. Nuestro modelo a seguir.

La modificación que nos va a servir de guía para este capítulo es:
- Unlock Basic Roads: http://smods.ru/archives/1733

El enlace no es para activar la modificación desde steam, si no que es para descargar la librería “.dll” directamente y así nos ahorramos un par de pasos. Además en este caso, tenemos la suerte que en el archivo comprimido que nos descargamos también se encuentra un archivo con el código fuente sin compilar.

Dentro del archivo comprimido nos encontramos con el archivo “UnlockBasicRoads.dll” que es la modificación compilada. También nos encontramos con la carpeta “Source” que contiene los códigos fuente. En dicha carpeta están, el archivo “UnlockBasicRoads.cs” que es el código fuente en c# de la modificación y la carpeta “ChirpLogger”.

¿Una carpeta “ChirpLogger”? bueno pues resulta que esta modificación hace uso del código de otra modificación que permite usar a Chirper como una consola y así enviarle mensajes. Cuando se desbloquean las calles, la modificación envía un texto al pajarito azul y este nos lo muestra como un mensaje del juego.

Tampoco es una mala práctica, antes de empezar con el código, instalar la modificación en el juego, probarla en un mapa nuevo y observar su comportamiento. No te olvides de desinstalarla antes de probar nuestra modificación.

2.2. “Espiando” la librería.

A pesar de tener el código fuente, se va a intentar ilustrar el proceso de descompilar una librería y observar su contenido. Como ya se vio en el capítulo anterior, el programa que se va a usar es (ILSpy) http://ilspy.net/ . En la página del programa, te descargas los binarios y ejecutas el archivo “IL.exe” para abrir el programa (no necesita ser instalado). Una vez abierto el programa, en la barra izquierda, seleccionamos todos los elementos ya cargados y con la tecla Supr. los eliminamos para que no nos estorben mucho. Posteriormente arrastramos nuestro archivo “UnlockBasicRoads.dll” a la barra izquierda recién vaciada.

Tras lo cual, vemos cómo aparece el nombre de la librería y su versión. Expandimos su contenido y nos encontramos con 5 nuevos apartados:

    - References
    - {} -
    - {} ChirpLogger
    - {} ChirpLogger.Internal
    - {} UnlockBasicRoads

El apartado de “References” es una buena guía para saber qué librerías del juego tenemos que referenciar en nuestro proyecto. Expandimos su contenido y nos encontramos con “ICities” y con “mscorlib”. La segunda es una librería del sistema y no necesitaremos referenciarla manualmente, pero la primera sí es una librería del juego y sí tendremos que referenciarla en nuestro proyecto.

Los demás apartados, con las “{}” delante, hacen referencia a espacios de nombres dentro de la librería, vamos a expandir “{} UnlockBasicRoads” que de momento es el único que nos interesa. Nos encontramos que este espacio de nombres contiene dos clases “UnlockBasicRoads” y “UnlockBasicRoadsMilestones”. Seleccionamos la primera y vemos como en la sección derecha del programa aparece el código en c# de esa clase. Que es el siguiente:

Código: Seleccionar todo
using ICities;
using System;

namespace UnlockBasicRoads {
    public class UnlockBasicRoads : IUserMod {
        public string Name {
            get  {  return "Unlock Basic Roads";  }
        }

        public string Description  {
            get { return "Unlocks Basic Roads without the need to place single road first";  }
        }
    }
}


Como ya vimos en el capítulo anterior esta es la clase que se encarga de definir la librería como una modificación apta para Cities Skylines. Pasemos pues a observar la siguiente clase, la seleccionamos y nos encontramos con:

Código: Seleccionar todo
using ChirpLogger;
using ICities;
using System;

namespace UnlockBasicRoads {
    public class UnlockBasicRoadsMilestones : MilestonesExtensionBase {
        public override void OnRefreshMilestones() {
            base.get_milestonesManager().UnlockMilestone("Basic Road Created");
            ChirpLog.Debug("Basic Road Created");
        }
    }
}


Muy bien, vamos a observar con más detalle este código, tenemos la clase “UnlockBasicRoadsMilestones” que hereda el comportamiento del módulo “MilestonesExtensionBase”. Con esta herencia tenemos la opción de sobreescribir la función “OnRefreshMilestones()” y tener acceso a “...UnlockMilestone(“...”);”

Todo esto viene a ser, el módulo “MilestonesExtensionBase” nos da acceso a ciertas funcionalidades sobre los objetivos del juego, por ejemplo, el primer objetivo del juego cuando creas un mapa nuevo es crear una calle básica de doble sentido, cuando se cumpla ese objetivo, el juego desbloqueará la calle básica de sentido único. Sobreescribiendo la función “OnRefreshMilestones()” podemos hacer que nuestra modificación ejecute el código que nosotros queramos cada vez que se actualice la lista de objetivos del juego. En la modificación que estamos analizando,
nos encontramos con:

Código: Seleccionar todo
 base.get_milestonesManager().UnlockMilestone("Basic Road Created");


Esta llamada a la función “.UnlockMilestones(“Basic Road Created");” le dice al gestor de objetivos del juego que considere como cumplido el objetivo “Basic Road Created” y a partir de ahí, el motor del juego se encargará de desbloquear la calle de sentido único.

La siguiente línea de código:

Código: Seleccionar todo
ChirpLog.Debug("Basic Road Created");


Le envía un mensaje de texto a Chiper a través de las funcionalidades implementadas en el espacio de nombres “ChirpLogger”.


De todo esto que hemos visto, lo primero que me viene a la mente es eliminar el uso de “ChirpLogger” y lo segundo es que al sobreescribir la función “OnRefreshMilestones()”, cada vez que el juego quiera actualizar el estado de los objetivos del nivel, nosotros le estamos diciendo que “Basic Road Created" está cumplido. La duda que me asalta es, si no bastaría con decirle una vez que “Basic Road Created” está cumplido. Pero eso lo exploraremos en el siguiente apartado.

2.3. Implementando.

Es momento de programar, abrimos nuestro Visual Studio, creamos un nuevo proyecto (C# - Class Library), y le enlazamos la librería “ICities.dll” (Project>Add Reference).

En nuestro código C# comenzamos poniendo las directivas:

Código: Seleccionar todo
   
using ICities;
using System;

A continuación la definición del espacio de nombres que va a usar nuestra modificación:

Código: Seleccionar todo
namespace DesbloqueaCallesBase {
}


Dentro del cuerpo del nuevo espacio de nombres añadiremos la clase que va a configurar nuestra modificación.

Código: Seleccionar todo
public class ModInfo : IUserMod {
    public string Name {
          get  {  return "Desbloquea calles base";  }
    }

    public string Description  {
           get { return "Modificación que desbloquea la calle básica de 
                              sentido único";  }
    }
}


Bien, ya tenemos lo básico para que el juego acepte nuestra librería. Ahora toca pensar, en qué momento, a lo largo de toda la ejecución del juego es más lógico que se le diga al gestor de objetivos que el objetivo “Basic Road Created" ha sido cumplido.

En la modificación de ejemplo, se hacía sobreescribiendo la función “OnRefreshMilestones()” del módulo “MilestonesExtensionBase” de la librería “ICities”, así que ahora sí vamos a ir a la documentación existente a buscar lo que podamos sobre el módulo mencionado. En la wiki del juego nos encontramos la sección (Mod Api) http://www.skylineswiki.com/Modding_API y nos dirigimos al apartado (“2.9.3 MilestonesExtensionBase”) http://www.skylineswiki.com/Modding_API#MilestonesExtensionBase encontrando lo siguiente:

IMilestones milestonesManager { get; set; }


Thread: Any
Gets the milestone manager interface
---------------------------------------------------------------

Acceso al gestor de objetivos del juego con el método get(). Se puede ejecutar en cualquier hilo del juego, es decir, desde el menú principal, desde una partida iniciada, etc.

void OnRefreshMilestones();


Thread: Simulation
Called every time the game checks updates the user progression status
---------------------------------------------------------------

Función que se llama cada vez que se actualiza los progresos en los objetivos del juego. Esta función sólo se ejecutará en el hilo de simulación del juego, es decir desde una partida iniciada.

Además en el apartado (“2.9 IMilestones”) http://www.skylineswiki.com/Modding_API#IMilestones nos encontramos:

void UnlockMilestone(string name);


Thread: Simulation
Unlocks the Milestone designated by the name parameter. Use EnumerateMilestones() to list all the available milestone strings
---------------------------------------------------------------

Función que al llamarla, nos permite decirle al gestor de objetivos del juego, que un objetivo concreto se ha cumplido. Esta función sólo se ejecutará en el hilo de simulación del juego.

Muy bien, como lo que queremos es que se complete el objetivo una vez durante la partida (lo lógico sería una vez termine de cargar el nivel) vamos a echarle un nuevo vistazo a la documentación y nos encontramos en ("2.7.3 LoadingExtensionBase")http://www.skylineswiki.com/Modding_API#LoadingExtensionBase lo siguiente:

void OnLevelLoaded(LoadMode mode);


Thread: Main
Invoked when a level has completed the loading process
The mode defines what kind of level was just loaded
---------------------------------------------------------------

Función que se llama una vez se ha completado el proceso de carga del nivel. Se ejecuta en el hilo principal.

Esto nos da el acceso al punto que queremos, pero no nos da acceso al hilo de simulación que es donde se ejecuta “.UnlockMilestone(string name);”. Seguimos buscando, y en la sección ("2.12.1 IThreading")http://www.skylineswiki.com/Modding_API#IThreading_2 nos encontramos con:

void QueueSimulationThread(Action action);


Thread: Any
Add an action to be executed in simulation thread
---------------------------------------------------------------

Añade una acción a ejecutar en el hilo de simulación

¿Action, y eso qué es? Bueno, eso es de las librerías del sistema de c#, más concretamente “mscorlib.dll”. Si están usando Visual Studio es posible que esté configurado para usar el framework “.Net Framework 4.5” y cuando uses Action y el juego ejecute tu modificación, este mostrará un mensaje de error diciendo que no encuentra “System.Action”. Esto se debe a que el juego usa una librería “mscorlib.dll” de una versión inferior y el sistema de excepciones produce un error. Lo vamos a solucionar dirigiéndonos a (Project> NameProject Properties…), dentro en la sección “Application” y en “Target framework:” seleccionamos “.Net Framework 3.5”. Y con esto se soluciona el dichoso error y podemos seguir explicando qué es una Action.

El uso de Action en este contexto retrasa la llamada de una función a un momento posterior en la ejecución de la modificación, dentro del hilo de simulación. Así que, crearemos una función que complete el objetivo y con la llamada a la función “.QueueSimulationThread(miFuncionCreada);” retrasaremos la ejecución de miFuncionCreada al momento que el juego “desee” dentro del hilo de simulación, pero, solo lo hará una vez.

Empezamos a implementar la clase que nos va a desbloquear las carreteras. Esta clase hereda el comportamiento del módulo “LoadingExtensionBase”, lo que le da acceso a la función “OnLevelLoaded(...)”. Dentro del cuerpo del espacio de nombres de nuestra modificación escribimos:

Código: Seleccionar todo
public class Desbloquea : LoadingExtensionBase {
}

Ahora, a esta clase le añadimos una función que sea la que haga cumplir el objetivo “Basic Road Created” al juego.


Código: Seleccionar todo
    public void desbloquearCB () {
         managers.milestones.UnlockMilestone("Basic Road Created");
    }


Posteriormente sobreescribimos la función “OnLevelLoaded(...)” para que se añada la función anterior a la cola de ejecución del hilo de simulación.

Código: Seleccionar todo
    public override void OnLevelLoaded(LoadMode mode) {
        managers.threading.QueueSimulationThread(desbloquearCB);
    }


Por último, prestemos atención al uso de “managers.milestones….” y “managers.threading….” que nos dan acceso a los gestores del juego de objetivos y de los hilos respectivamente. Todos los módulos que nos proporciona el juego para heredar comportamientos (por ejemplo, “LoadingExtensionBase”) tienen implementado un acceso a un gestor de gestores y así podemos llamar a funciones de otros gestores sin tener que heredar su comportamiento.

2.4. Resumen.

- Visual Studio:
Cambiar de framework: (Project> NameProject Properties…) ->“Application” -> “Target framework:” [.Net Framework 3.5]

- Código C# - Desbloquea calles base:

Código: Seleccionar todo
using ICities;
using System;

namespace DesbloqueaCallesBase {
    public class ModInfo : IUserMod {
        public string Name {
            get  {  return "Desbloquea calles base";  }
        }

        public string Description  {
            get { return "Modificación que desbloquea la calle básica de  sentido único";  }
        }
    }
    public class Desbloquea : LoadingExtensionBase {
        public void desbloquearCB () {
            managers.milestones.UnlockMilestone("Basic Road Created");
        }
        public override void OnLevelLoaded(LoadMode mode) {
            managers.threading.QueueSimulationThread( desbloquearCB);
        }
    }
}



PD: Próximo capítulo: "Opciones de configuración."
Avatar de Usuario
wyllman
Turista
Turista
 
Mensajes: 40
Registrado: 30 May 2010, 21:15
Género:

Re: [Tutorial] CiSk - C# Modding: 002 - Investigando.

Notapor benzoll » 27 Jul 2015, 07:18

Con este 2º tutorial, voy a intentar personalizar un par de mods:
1/Tree Brush
http://steamcommunity.com/sharedfiles/f ... =406723376
para ponerle un par de pinceles como salen en "distritos", y bajarle la densidad de arboles puestos.
2/All 25 Areas purchasable
http://steamcommunity.com/sharedfiles/f ... =405810376
para cambiarlo a la 1º meta (milestone) que da una parcela, y ahí libere las 24 restantes para su compra.
Avatar de Usuario
benzoll
Ciudadano
Ciudadano
 
Mensajes: 375
Registrado: 08 Mar 2013, 19:23
Ubicación: Asturias
Género:

Re: [Tutorial] CiSk - C# Modding: 002 - Investigando.

Notapor wyllman » 27 Jul 2015, 09:36

Me alegra ver que alguién se anima también a trastear con el motor del juego =D> jejeje Yo me he animado a hacer estos tutoriales porque quiero hacerme mi propia modificación que sea una recopilación de todas las pequeñas funcionalidades que me gustan (de otras ya creadas) y no tener que instalarlas todas por separado. Y por otro lado me gustaría recuperar una par de aspectos perdidos del antiguo Cities XL. Como esto me va a llevar tiempo, a medida que aprendo a tratar con Cities Skylines voy creando el tutorial y así ahorrarle algo de tiempo de investigación a todo aquel que, como tú, se anime a hacer sus propias modificaciones.

Si necesitas ayuda, no dudes en comentarlo por aquí, estaré encantado de ayudarte en lo que pueda y aprender de tus experiencias al igual que intento que puedan aprender de las mías :mrgreen:

Un saludo y suerte con el código.


PD : "Si compila a la primera, es que algo has hecho mal. :wall: " - Proverbio chino del programador jajajaja.
Avatar de Usuario
wyllman
Turista
Turista
 
Mensajes: 40
Registrado: 30 May 2010, 21:15
Género:

Re: [Tutorial] CiSk - C# Modding: 002 - Investigando.

Notapor benzoll » 27 Jul 2015, 20:17

Mod: All 25 Areas purchasable (con la ultima meta conseguida, la 13, da para comprar 17 parcelas mas en vez de una, total 25, se pueden comprar 9, o 12 o 18, las que se quieran, no es que el mapa pase a 25 parcelas directo).

Código: Seleccionar todo
using ICities;
using System;

namespace MaxAreaMod
{
   public class MaxArea : IUserMod
   {
      public string Name
      {
         get
         {
            return "All Areas purchaseable";
         }
      }

      public string Description
      {
         get
         {
            return "Purchase up to 25 areas instead of 9";
         }
      }

      public void OnLoad()
      {
      }

      public void OnUnload()
      {
      }
   }
}


Código: Seleccionar todo
using ICities;
using System;

namespace MaxAreaMod
{
   public class MaxAreaForGood : IAreasExtension
   {
      public void OnCreated(IAreas areas)
      {
         areas.maxAreaCount = 25;
      }

      public void OnReleased()
      {
      }

      public bool OnCanUnlockArea(int x, int z, bool originalResult)
      {
         return originalResult;
      }

      public int OnGetAreaPrice(uint ore, uint oil, uint forest, uint fertility, uint water, bool road, bool train, bool ship, bool plane, float landFlatness, int originalPrice)
      {
         return originalPrice;
      }

      public void OnUnlockArea(int x, int z)
      {
      }
   }
}


Llevo media tarde buscando una referencia a milestone (objetivo/logro/meta), y no la encuentro o no la hay, ¿Cómo han colocado este mod para que actue solo en la ultima meta (milestone) que da la ultima parcela y los monumentos? :wall:
A seguir investigando. :shock:
Avatar de Usuario
benzoll
Ciudadano
Ciudadano
 
Mensajes: 375
Registrado: 08 Mar 2013, 19:23
Ubicación: Asturias
Género:

Re: [Tutorial] CiSk - C# Modding: 002 - Investigando.

Notapor wyllman » 27 Jul 2015, 22:35

"Edito la respuesta entera porque me ha quedado muy desordenada."

La modificación que muestras de desbloquear el mapa, no parece estar usando el gestor de milestones (hereda de la interfaz IAreasExtension).
La documentación que podemos encontrar es esta: - 2.2 IAreas: http://www.skylineswiki.com/Modding_API#IAreas

Da la impresión que el juego separa el asunto de completar objetivos y desbloquear en mapa en dos partes bien diferenciadas.

Esta modificación lo único que hace es poner el contador de límite de parcelas a 25, creo que en el juego original está a 8. Lo realiza con la siguiente línea:

Código: Seleccionar todo
areas.maxAreaCount = 25;


El resto del código realiza exáctamente lo mismo que el juego original. Recuerda, heredar de una interfaz te obliga a implementar todas las funciones abstractas que contenga dicha interfaz. Aunque esas funciones esten vacías y no hagan nada. La ventaja es que con las interfaces puedes heredar de varias en la misma clase.

---------------------------------------------------------

En otro aspecto, para manejar mejor el gestor de objetivos(milestonesManager) tenemos una función que nos mostrará todos los títulos de los objetivos creados.

http://www.skylineswiki.com/Modding_API#IMilestones

string[] EnumerateMilestones();

Thread: Any
Returns an array of string containing the name of all the unlockable milestones


al ser llamada, esta función nos retorna un array, en el que cada poscición del mismo contiene un string con el título de uno de los objetivos del juego. Puedes imprimir por consola cada uno de ellos y tener tu primera lista de objetivos implementados en el juego.

PD: En el cuarto capítulo del tutorial avanzaré un poco más en el uso del ILSpy y recorrer las librerías internas del juego.
Avatar de Usuario
wyllman
Turista
Turista
 
Mensajes: 40
Registrado: 30 May 2010, 21:15
Género:

Re: [Tutorial] CiSk - C# Modding: 002 - Investigando.

Notapor benzoll » 28 Jul 2015, 00:19

Gracias. Esa impresión me estaba dando: no hay referencia ninguna a las "metas", el juego ha dejado ampliar a 25 parcelas cambiando el numero con esa línea de código y misteriosamente salen en la ultima "meta" las que faltan: 17, mas 8 que ya tenemos.
Es lo que hay. MI gozo en un pozo, :( jeje.
Voy a mirar el "tree brushe" , hay que seguir trasteando. :P
Avatar de Usuario
benzoll
Ciudadano
Ciudadano
 
Mensajes: 375
Registrado: 08 Mar 2013, 19:23
Ubicación: Asturias
Género:

Re: [Tutorial] CiSk - C# Modding: 002 - Investigando.

Notapor wyllman » 28 Jul 2015, 09:01

No lo he probado, pero se me ocurre que a lo mejor, modificando:

Código: Seleccionar todo
public bool OnCanUnlockArea(int x, int z, bool originalResult) {
         return true; //original => "return originalResult;"
}


Hay una modificiación que te desbloquea todas las areas (las 25) desde el principio, pero, no te las desbloquea para comprar, si no que te las debloquea totalmente para construir, modificando esta función:

Código: Seleccionar todo
public void OnUnlockArea(int x, int z) {
   // No recuerdo el código, en cuanto pueda y lo encuentre lo posteo
}


¿Qué era exactamente lo que querías hacer?
Avatar de Usuario
wyllman
Turista
Turista
 
Mensajes: 40
Registrado: 30 May 2010, 21:15
Género:

Re: [Tutorial] CiSk - C# Modding: 002 - Investigando.

Notapor benzoll » 28 Jul 2015, 21:43

No te preocupes, cuando quiera todo el mapa desbloqueado desde el inicio lo da el mod original de Colossal: "milestones unlock" combinado con "All 25 Areas purchasable" y tema solucionado.
Estoy con "tree brushe" :

Código: Seleccionar todo
using ColossalFramework;
using ICities;
using System;
using UnityEngine;

namespace TreeBrush
{
   public class TreeBrushAddin : IUserMod, IThreadingExtension
   {
      private SavedInputKey increaseKey;

      private SavedInputKey decreaseKey;

      public string Description
      {
         get
         {
            return "Enable tree brush ingame";
         }
      }

      public string Name
      {
         get
         {
            return "Tree brush";
         }
      }

      public void OnAfterSimulationFrame()
      {
      }

      public void OnAfterSimulationTick()
      {
      }

      public void OnBeforeSimulationFrame()
      {
      }

      public void OnBeforeSimulationTick()
      {
      }

      public void OnCreated(IThreading threading)
      {
      }

      public void OnReleased()
      {
      }

      public void OnUpdate(float realTimeDelta, float simulationTimeDelta)
      {
         TreeTool treeTool = ToolsModifierControl.get_toolController().get_CurrentTool() as TreeTool;
         if (treeTool == null)
         {
            return;
         }
         if (this.increaseKey == null)
         {
            this.increaseKey = new SavedInputKey(Settings.mapEditorIncreaseBrushSize, Settings.gameSettingsFile, 270, false, false, false, true);
            this.decreaseKey = new SavedInputKey(Settings.mapEditorDecreaseBrushSize, Settings.gameSettingsFile, 269, false, false, false, true);
         }
         if (Input.GetKeyDown(this.increaseKey.get_Key()))
         {
            if (treeTool.m_mode == null)
            {
               treeTool.m_brushSize += 50f;
            }
            else
            {
               treeTool.m_mode = 0;
               treeTool.m_strength = 500f;
               treeTool.m_brushSize = 32f;
            }
         }
         if (Input.GetKeyDown(this.decreaseKey.get_Key()))
         {
            treeTool.m_mode = 0;
            treeTool.m_strength = 2000f;
            treeTool.m_brushSize -= 50f;
            if (treeTool.m_brushSize < 32f)
            {
               treeTool.m_mode = 1;
               treeTool.m_brushSize = 32f;
            }
         }
      }
   }
}


- ¿ qué es la f detrás de los números?
- "using ColossalFramework;" esto no esta a la vista, esta metido en ColossalManaged y no se puede escoger como referencia, no se como lo haría. Poniendo ColossalManaged vale.
- El código no parece correcto, porque size (tamaño pincel) va de 50 a 2000 y strenght (densidad/grosor) de 0.01 a 1 según wiki oficial del juego, y aquí parecen cambiados.
http://www.skylineswiki.com/Map_Editor
Este mod mete al juego el pintar arboles del editor de mapas, por lo que entiendo. Quiero cambiar el grosor, porque siempre es muy grueso (pinta muchísimos arboles, demasiados).
Me despista la f, me despistan los numeros cambiados y me despistan la pila errores que me da al compilar.. :lol: :lol:
Me lo tomo con buen humor, esto no es tan fácil como coger un mod, personalizarlo y volver a compilar, falla. Sin hacer ningún cambio, al volver a compilar ya falla.. :roll:
En este seria sencillo: en todos los strength esperaba encontrar un 1, los cambiaba a 0.33 por ej, y listo, pero..
Avatar de Usuario
benzoll
Ciudadano
Ciudadano
 
Mensajes: 375
Registrado: 08 Mar 2013, 19:23
Ubicación: Asturias
Género:

Re: [Tutorial] CiSk - C# Modding: 002 - Investigando.

Notapor wyllman » 29 Jul 2015, 03:05

Lo de la f después de ciertos números, es una de esas pijadas de c# con las que hay que lidiar. Cuando vayas a usar un número decimal le tienes que poner la f detrás para que el compilador de c# sepa que es así (también se les suele llamar números de coma flotante). Por ejemplo si el strenght va de 0.01 a 1 y tu quieres ponerle un 0.8, en c# habría que poner "0.8f".

Recuerda, solo puedes usar un número decimal en una variable de tipo float (https://msdn.microsoft.com/es-es/library/b1e65aza%28v=vs.120%29.aspx)

Código: Seleccionar todo
float y = 4.5f;


Otra curiosidad para el uso de la f. En el siguiente código:

Código: Seleccionar todo
float resultado = 1 / 2;


resultado debería ser 0.5 ya que es una variable de tipo flotante, pero en realidad resultado es 0 porque al hacer la división así, se está realizando una división de números enteros y el resto se desprecia. Siempre que el denominador sea un entero, la división será entre enteros. Así que una forma rápida es convertir el denominador en flotante añadiendole una f.

Código: Seleccionar todo
float resultado = 1 / 2f;




Efectivamente el mod parece pasarse de rangos descaradamente, pero puede que el motor del juego tenga esa "falta de comprobaciones" o lo de la wiki es una recomendación.

ColossalFramework es el espacio de nombres general, definido en la librería ColossalManaged.dll. Con referenciar esta .dll en la configuración del proyecto deberías poder usar la directiva "using ColossalFramework;" sin problemas.

PD: Si quieres compilar el código que muestras tal cual, asegurate de tener referenciadas en tu proyecto las siguientes librerías:
-ICities.dll
-Colossalmanaged.dll
-UnityEngine.dll
-Assembly-CSharp.dll (Por si acaso :) )
Avatar de Usuario
wyllman
Turista
Turista
 
Mensajes: 40
Registrado: 30 May 2010, 21:15
Género:

Re: [Tutorial] CiSk - C# Modding: 002 - Investigando.

Notapor benzoll » 27 Feb 2016, 21:56

Wyllman, ¿andas por aqui todavia?
Tengo un drama con mod "dropouts", jeje. A ver si hay manera de echarle un vistazo.
Avatar de Usuario
benzoll
Ciudadano
Ciudadano
 
Mensajes: 375
Registrado: 08 Mar 2013, 19:23
Ubicación: Asturias
Género:


Volver a Modding

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

Comunidad Capital Sim (2003-2008) webmaster arroba capitalsim.net