Jump to content

mnn

Members
  • Posts

    298
  • Joined

  • Last visited

Posts posted by mnn

  1. Glad to see some tutorials in Scala :). I found a bug and some cosmetic blemishes. Highlighted version on gist github - https://gist.github.com/mnn/57cc01980312289f39e9 (it's a working Scala script).

     

    import scala.runtime.ScalaRunTime.stringOf
    import scala.collection.JavaConverters._
    
    // stuff for verifying results, skip to case defs (comment -- 1 --)
    def doVerify[A](name: String, origRes: A, myRes: A) {
      val equals = origRes match {
        case a: Array[_] => a.sameElements(myRes.asInstanceOf[Array[_]])
        case _ => origRes.equals(myRes)
      }
      if (equals) println(s"Case '$name' fine: ${stringOf(myRes)}")
      else println(s"Case '$name' wrong:\n${stringOf(origRes)}\nvs.\n${stringOf(myRes)}")
    }
    
    def verify[A, R](name: String, orig: (A) => R, mine: (A) => R, testVal: A) {
      doVerify(name, orig(testVal), mine(testVal))
    }
    
    def verify[R](name: String, orig: () => R, mine: () => R) {
      doVerify(name, orig(), mine())
    }
    
    // -- 1 --
    def case1orig(oBounds: Seq[int]) = {
      var boxes = Seq(oBounds(6))
      for (s <- 0 until 6) boxes :+= oBounds(s)
      boxes
    }
    
    def case1mine(oBounds: Seq[int]) = oBounds.last +: oBounds.init
    
    verify("1", case1orig, case1mine, 0 to 6)
    // -------
    
    // -- 2 --
    def case2orig() = {
      val w = "someExpression"
      w
    }
    
    def case2mine() = "someExpression"
    
    verify("2", case2orig, case2mine)
    
    // same with returning in generateBoxes, generateCollisionBoxes 
    // -------
    
    // -- 3 --
    // Does getOcclusionBoxes even compile? There is no return value in "if" branch.
    /*
        override def getOcclusionBoxes = {
            import mlb.technica.experience.PipeBoxes._
            if (true)
            else Seq(oBounds(6)).asJava
        }
    */
    
    // Possibly what you meant:
    def case3orig(oBounds: Seq[int]) = {
      if (true) Seq().asJava
      else Seq(oBounds(6)).asJava
    }
    
    def case3mine(oBounds: Seq[int]) = Seq().asJava
    
    verify("3", case3orig, case3mine, 0 to 6)
    // -------
    
    // -- 4 --
    // Some implementation of used classes in snippet
    class Cuboid6(var a: Double, var b: Double, var c: Double, var d: Double, var e: Double, var f: Double) {
      def apply(r: Rotation): Cuboid6 = {
        a -= r.x
        b -= r.y
        c -= r.z
        d -= 7 * r.x
        e -= 9 * r.y
        f -= 13 * r.x
        this
      }
    
      override def equals(that: Any) =
        that match {
          case t: Cuboid6 => t.a == a && t.b == b && t.c == c && t.d == d && t.e == e && t.f == f
          case _ => false
        }
    
      override def toString() = s"Cuboid6($a, $b, $c, $d, $e, $f)"
    }
    
    class Rotation(val x: Double, val y: Double, val z: Double) {
      def at(v: Vector3): Rotation = new Rotation(x + v.x, y + 2 * v.y, z + 3 * v.z)
    }
    
    object Rotation {
      val sideRotations = (0 to 6).map(v => new Rotation(1.0 / (v + .1), 5.0 / (v + 2), 5 * (v - 3)))
    }
    
    class Vector3(val x: Double, val y: Double, val z: Double)
    
    object Vector3 {
      lazy val center = new Vector3(11, 23, 27)
    }
    
    // PipeBoxes.oBounds
    def case4orig() = {
      val boxes = new Array[Cuboid6](7)
      val w = 2 / 8D
      boxes(6) = new Cuboid6(0.5 - w, 0.5 - w, 0.5 - w, 0.5 + w, 0.5 + w, 0.5 + w)
      for (s <- 0 until 6)
        boxes(s) = new Cuboid6(0.5 - w, 0, 0.5 - w, 0.5 + w, 0.5 - w, 0.5 + w).apply(Rotation.sideRotations(s).at(Vector3.center))
      boxes
    }
    
    def case4mine() = {
      val w = 2 / 8D
      val (m, p) = (.5 - w, .5 + w)
      ((for (s <- 0 until 6) yield new Cuboid6(m, 0, m, p, m, p).apply(Rotation.sideRotations(s).at(Vector3.center)))
        :+ new Cuboid6(m, m, m, p, p, p)).toArray
    }
    
    verify("4", case4orig, case4mine)
    

  2. I would like to have a second (obfuscated) jar generated from certain packages. I have almost no experiences with Gradle (but I guess this is rather Forge Gradle question, because I don't know where/how obfuscation is going on). How to achieve this? I tried looking for some Forge Gradle documentation, but without luck.

     

    PS: I found some examples of generating API and dev (not obfuscated) jars, but not a one with obfuscated stuff.

  3. Update: in older version 1060 it's working fine - full log at

    eclipse\logs\fml-client-latest.log

    . In version 1121 (recommended build) it seems to be broken (fixing transformer crash hasn't change a thing). "Solving" the issue by outputting all to info level feels very dirty, but I don't have a slightest idea how to fix it :'(.

  4. I can't find location of full logs (it used to be in

    mcp\jars\ForgeModLoader-client-0.log

    ). I saw some references to

    fml-client/server-latest.log

    on this forum, I found only

    eclipse\logs\latest.log

    and it's just a copy of console output (no more detailed levels). What needs to be setup to get those full logs or where are they hidden (search for

    *.log

    was fruitless)? Or another possibility, FML isn't logging from start so crash on transformer results in no detailed logs? :-\

  5. Always keep in mind though that reflection gives quite a performance penalty.

    The penalty is not always high as shown for example here. Also if reflection is used not that often (e.g. few calls after an entity spawn or after world is created) it really doesn't matter what technique is used (but ATs are more difficult to setup and can change a lot in future versions, just as changed now with gradle).

  6. Yes, it DOES fucking matter. Don't just tell people they are wrong when you have no clue yourself.

    Items must be created in preInit as of 1.7 and it has been recommended to do so in the Javadocs ever since.

     

    I'm curious where in JavaDocs is this described, because my local Forge sources look like this (load event, #1060):

    /*
    * Forge Mod Loader
    * Copyright (c) 2012-2013 cpw.
    * All rights reserved. This program and the accompanying materials
    * are made available under the terms of the GNU Lesser Public License v2.1
    * which accompanies this distribution, and is available at
    * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
    * 
    * Contributors:
    *     cpw - implementation
    */
    
    package cpw.mods.fml.common.event;
    
    import cpw.mods.fml.common.LoaderState.ModState;
    
    public class FMLInitializationEvent extends FMLStateEvent
    {
    
        public FMLInitializationEvent(Object... data)
        {
            super(data);
        }
        
        @Override
        public ModState getModState()
        {
            return ModState.INITIALIZED;
        }
    
    }

     

    No hint whatsoever what exactly should be going on there (nothing in LoaderState as well).

     

    PS: PreInit is considerably longer, but there are no comments about this too.

  7. This mod can be combined with some on-crash-restart script/app (e.g. MineStart). But yes, if you're looking for auto-restart then this mod isn't doing that exactly - it's supposed to be part of an "on demand" service. This mod handles auto-shuttingdown, but if you want players to be able to start server, you have to add another part - in OP is a link to the blog post which describes already working solution (the "starting" part there is a simple web page in php).

  8. I'm totally ignoring your crafting system and writing it from a perspective of vanilla crafting (if you are doing it same/similar way all of this should apply).

     

    To make a recipe you implement

    IRecipe 

    and register it - e.g.

    GameRegistry.addRecipe(new MyRecipe(params))

    . In this custom recipe you can specify what is a result of crafting depending on a current crafting matrix (input items = ItemStacks). Then you simply copy generic crafting result and add/modify needed NBT tags. example

     

    I haven't tried it, but if you override

    public Icon getIconIndex(ItemStack par1ItemStack)

    you should be able to get icons depending on NBT.

     

    -Function 1, 2, 3, ..., n,  that will be called if an item has ,,this" NBT.

    I'm not sure what this mean. If you want initialize the item, you can do it from recipe. If you want custom damage or other attribute you can change/set it in recipe when creating item as well.

  9. I think even using the other FML loader you still need to add zips/jars to the classpath. I'm curious why the urlclassloader isn't working (the snippet in the answer expects jar/zip file, not a directory - that can be otained e.g.

    new File("dirPath").listFiles()

    ).

     

    Do you have good path? Do you have properly organized insides of the jar/zip?

  10. 1. Blocks don't have textures when placed on the world but they do have in the creative tab.

    2. When I drop the block with metadata 1 and 0, they both make a single stack and after I pick it up, the stack will be blocks wit metadata 0.

    3. A weird problem with names.

    I think all problems are related to your implementation of custom ItemBlock. But looking at your TE, it can't really work.

     

    public class TileEntityMegaBlock extends TileEntity
    {
    // definitely wrong, or is your intention to have only placed one subtype of blocks at one time in all your worlds?
    public static int blockMetadata;
    
    ....	
    // ehm, what for?
    public TileEntity returnTE()
    {
    	return this;
    }
    }
    

     

    You have to implement placing method in ItemBlock and make sure the TE of newly placed block has set proper subtype (matching item damage of ItemBlock). Your TE must implement NBT serialization or you lose your subtype information every time a custom block is unloaded/loaded. Also when breaking a block the item which drops must have set damage matching the destroyed block's subtype (from its TE) .

     

    public class BlockMegaBlock extends BlockContainer
    {
        private static TileEntity TE  = new TileEntityMegaBlock();
    

     

    Looking at this I see you should read more about basic classes Minecraft uses before trying to implement "subtypes" - e.g. this blog is nice.

     

    PS: I recommend to not exchange terms metadata and item damage. Item damage can be used when placing a block (in custom ItemBlock), but it does not map 1:1 to metadata (which are limited to 16 values, item damage has full integer range [~65k?]).

  11. The workaround posted by myoKun345 seems to be working, I'll have to automatize it (bash script?), because doing it manually is quite tedious and error prone (forgetting remove files from lib).

     

    Just wondering, who is "responsible" for Scala support? I know that in older MCP versions FML/Forge was doing some patching of MCP scripts, but I have no idea how it's done now.

     

    I guess I was a bit naive to expect the scala support is in stable ready-to-use state :'(.

  12. To replace ore just after being generated you can subscribe to

    PopulateChunkEvent.Post

    . If you mean replacing ores in already generated world then I'd use

    ChunkEvent.Load

    , replace ores and mark this chunk as processed (and save it, we don't want to process already processed chunks every time chunk loads).

     

    In config being able to input ID or NAME would be nice. In code you should work with IDs - compairing names (= string cmp) of every block in a chunk, that would be awful.

     

    I have a feeling I somewhere saw similar project to what you're describing, are you sure it hasn't been already done?

  13. I don't think this is a good idea. Every "protection" (I can think of) can be circumvented, if some modder would want to modify your recipes, he/she (if knowledgeable enough) will.

     

    If I understood it correctly what you're doing then you're checking if any mod changed crafting list (e.g. added it's own recipe using only its stuff) - you should check only your recipes. But even then one might (via reflection) change internals of your recipe so you'd have to do a deep checking. But then some mod could change your backup copy of your recipes (reflection?). Or the mod could just wait until you make a check and modify all recipes later. You could check all your recipes periodically, but that would cost some player's resources and could be still circumvented - e.g. just before your check just switch to "good" recipe set and after check switch again. Or via ASM rewrite crafting code entirely. There is surely more ways of protection and more ways of bypassing...

     

    You can't really have 100% control over your recipes - it all boils down to whether other modders respect your wish regarding recipe changes.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.