public static IEnumerator LineSurface(Emplacement place, OptionEffect options) { Vector3i shape = options.OptionShape.shape; /// (avancée, hauteur, largeur) Vector3i above = Vectors.Up; Vector3i pos = place.ipos; Vector3i offsetSurface = new Vector3i(0, options.OptionShape.offsetSurface, 0); bool reverse = options.OptionShape.reverse != ""; float pace = options.OptionShape.pace; bool collapse_once = options.OptionShape.reverse == "once"; Block air = Block.GetBlockByName("air", false); Block blk = options.OptionBlock.block; BlockSetter setter = new BlockSetter(options.OptionBlock); /// IntLine traj = new IntLine(place.ipos, Vectors.Float.UnitX); IntLine traj = new IntLine(place.ipos, Emplacement.Truncate(place.direction, true, true)); for (int avance = 0; avance < shape.x; avance++) { Vector3i where = traj.Get(avance); Debug.Log("LineSurface " + avance.ToString()); IntLine orth = new IntLine(Vectors.ToFloat(where), Vectors.Float.UnitZ); foreach (int ligne in LR(shape.z)) { Vector3i at = orth.Get(ligne); //Debug.Log("Line Surface inner " + p.ToString()); at = Geo3D.Surface(at); // I don't need surface before orthogonal ... surface made after setter.Apply(at + above + offsetSurface); } setter.Push(); yield return(new WaitForEndOfFrame()); } }
public Emplacement(Entity target, OptionEffect options) { // Debug.Log("Emplacement 'at' = " + options.at); // position = Vectors.ToInt(target.position); position = target.position; EntityPlayer player = target as EntityPlayer; // case of Z : get their target (player or direction or focus) if (player == null) { return; } if (options.at == "ray") { position = Geo3D.intersectLook(player); } direction = Geo3D.directionLook(player); if (options.th == "true") { int h = (int)target.world.GetTerrainHeight(ipos.x, ipos.z); Debug.Log(string.Format("GetTerrainHeight {0} => {1}", position, h)); position.y = h; } }
public static IEnumerator SmokeGhost(EntityPlayer player, Emplacement place, OptionEffect options) { // onFire p_onFire Entity Requested = Spawn(place.position, "zombieMoeGhost"); // invisibleGhost zombieBoe int eid = Requested.entityId; yield return(WaitEntity(Requested)); Entity ent = GameManager.Instance.World.GetEntity(eid); if (ent == null) { Debug.Log(String.Format("SmokeGhost failed entity {0} {1}", eid, Requested)); yield break; } EntityAlive entity = ent as EntityAlive; string buffname = "buffInfiniteSmoke0"; if (entity != null) { if (!entity.Buffs.HasBuff(buffname)) { entity.Buffs.AddBuff(buffname); } } }
public static IEnumerator CactusGrowth(Entity player, Emplacement place, OptionEffect options) { Vector3i where = Geo3D.Surface(place.ipos) + Vectors.Up; string[] cactuses = new String[] { "treeCactus04", "treeCactus05", "treeCactus06", "treeCactus03", "treeCactus02", "treeCactus01" }; foreach (string blk in cactuses) { BlockSetter.SetBlockAt(where, Block.GetBlockByName(blk, false), options); yield return(new WaitForSeconds(1f)); } }
public OptionEffect Copy() { OptionEffect copied = this.MemberwiseClone() as OptionEffect; copied.OptionBlock = this.OptionBlock.Copy() as BlockSetter.Options; copied.OptionItem = this.OptionItem.Copy() as EffectsItem.Options; copied.OptionEntity = this.OptionEntity.Copy() as EntityCreation.Options; copied.OptionShape = this.OptionShape.Copy() as EffectsGround.Options; return(copied); }
public static void DynamicSizeVis(EntityPlayer player, Emplacement place, OptionEffect options) { // TODO: use size option List <Entity> entitiesInBounds = GameManager.Instance.World.GetEntitiesInBounds(typeof(EntityZombie), new Bounds(place.position, Vector3.one * 2f * 10f), new List <Entity>()); foreach (Entity entity in entitiesInBounds) { Zombiome.Routines.Start(TestDynamicSizeVis(entity)); } }
public static void Explosion(EntityPlayer player, Emplacement place, OptionEffect options) { /// effet graphique seul (mm si molo contient des degats, ils concernent le onImpact, pas l'explosion elle meme) /// ItemClass itemClass = ItemClass.GetItemClass("thrownAmmoMolotovCocktail", false); Debug.Log(String.Format("Explosion --> {0}", itemClass)); // GameManager.Instance.ExplosionServer(0, place.position, place.position, Quaternion.identity, new ExplosionData(itemClass.Properties), player.entityId, 0.1f, false, null); // try -1 GameManager.Instance.ExplosionServer(0, place.position, place.ipos, Quaternion.identity, new ExplosionData(itemClass.Properties), -1, 0.1f, false, null); // try in the air // altérer particule pour toutes les essayer }
public static IEnumerator TrapLine(Entity player, Emplacement place, OptionEffect options) { /// TODO: recoder ca avec rift Vector3i offsetSurface = new Vector3i(0, options.OptionShape.offsetSurface, 0); Vector3i pos = place.ipos; // size = E/W=largeur, hauteur, N/S profondeur (portee) Vector3i size = options.OptionShape.shape; Vector3 base_direction = Emplacement.Truncate(place.direction, true, true); float pace = 0.1f; // TODO pace in option Block air = Block.GetBlockByName("air", false); // The air instance could prolly be shared ... // Block blk = options.OptionBlock.block; int portee = 100; BlockSetter setter = new BlockSetter(options.OptionBlock); BlockSetter setterAir = new BlockSetter(options.OptionBlock.Copy()); setterAir.options.block = air; Vector3 posf = Vectors.ToFloat(pos + offsetSurface); // string[] random_blocks = new string[]{"trapSpikesWoodDmg0", "trapSpikesWoodDmg1", "trapSpikesWoodDmg2"}; // Block[] random_blocks = options.OptionBlock.blocks; Vector3i start = Geo3D.Surface(place.ipos); for (int k = 0; k < 10; k++) { Vector3 direction = base_direction + Vectors.Float.Randomize(GameManager.Instance.World.GetGameRandom(), 0.1f); direction.y = 0; direction = direction.normalized; // IntLine traj = new IntLine(start, direction); //east IEnumerable <Vector3i> segment = IntLine.Segment(Vectors.ToFloat(start), direction, 1, 10); // skip 0 intersecting with the previous foreach (Vector3i where in segment) { Vector3i Swhere = Geo3D.Surface(where); // randomisation : "trapSpikesWoodDmg0-2" // string rdm = random_blocks[(int) Math.Floor(GameManager.Instance.World.GetGameRandom().RandomFloat*3)]; // setter.options.block = Block.GetBlockByName(rdm, false); // Block rdm = setter.Apply(Swhere + Vectors.Up); setter.Push(); start = Swhere; yield return(new WaitForEndOfFrame()); } yield return(new WaitForSeconds(0.5f)); } }
public static IEnumerator SpawnAndbuff(EntityPlayer player, Emplacement place, OptionEffect options, Entity[] track = null) { /** Spawn and wait for callback before applying buff * * NB: waiting extra dt before applying buff is important * - Some entities just die, I don't know why. There is nothing at the spawn point, * they are not too far away from player (terrain heigth is known, althoug it happens more for distant ghosts) * - Waiting may or may not decrease the failure rate, but it helps the ghost activity to count them and * avoid many additionnal creations * - Because Ghost activity yield the waiter, this spread out creation and may help (too many spawn at once ?). * But is is also costly to wait (more hanging coroutines) * * NB2) the problem is NOT caused by : MyAddParticle, ghost type, ghost small buf, invisibility, GetTerrainHeight check * */ Entity Requested = Spawn(place.position, options.OptionEntity.entity); int eid = Requested.entityId; yield return(WaitEntity(Requested, 2f, track)); Entity ent = GameManager.Instance.World.GetEntity(eid); if (ent == null) { Debug.Log(String.Format("SpawnAndbuff failed entity {0} {1}", eid, Requested)); yield break; } EntityAlive entity = ent as EntityAlive; if (ent == null) { Printer.Print("Entity is not alive !"); yield break; } string buffname = options.OptionEntity.buff; if (entity != null) { if (entity.Buffs == null) { Printer.Print("Entity.buff == null !"); } else if (!entity.Buffs.HasBuff(buffname)) { entity.Buffs.AddBuff(buffname); } } }
public static IEnumerator Wave(Entity _player, Emplacement place, OptionEffect options) { /* NB: position ou ray peuvent etre ds le vide. Il faut partir une case dessous et not erase ? */ Vector3i offsetSurface = new Vector3i(0, options.OptionShape.offsetSurface, 0); Vector3i pos = place.ipos; // size = E/W=largeur, hauteur, N/S profondeur (portee) Vector3i size = options.OptionShape.shape; Vector3 direction = Emplacement.Truncate(place.direction, true, true); float pace = 0.1f; // TODO pace in option Block air = Block.GetBlockByName("air", false); // The air instance could prolly be shared ... Block blk = options.OptionBlock.block; int portee = 10; // [!] BlockSetter setter = new BlockSetter(options.OptionBlock); BlockSetter setterAir = new BlockSetter(options.OptionBlock.Copy()); setterAir.options.block = air; Vector3 posf = Vectors.ToFloat(pos + offsetSurface); for (int forward = 1; forward <= portee; forward++) { foreach (int width in LR(size.x)) { setter.Apply(Vectors.Toward(posf, direction, forward)); // avant de la vague setter.Push(); yield return(new WaitForSeconds(pace)); setter.Apply(Vectors.Toward(posf, direction, forward - 1)); setter.Apply(Vectors.Toward(posf, direction, forward - 1) + Vectors.Up); // if not exist material to speed up? setter.Push(); yield return(new WaitForSeconds(pace)); if (forward > 3) // TODO: test existing ? { setterAir.Apply(Vectors.Toward(posf, direction, forward - 1 - 2)); setterAir.Apply(Vectors.Toward(posf, direction, forward - 1 - 2) + Vectors.Up); setterAir.Push(); } } // __BUG(); // FIXME test } }
/* * * Options: * - ground (water, traps) * - recursion * - size / depth (puis avant) * - other content : Z, animal, torch, lights ... * */ public static IEnumerator Rift(EntityPlayer player, Emplacement place, OptionEffect options) { /* * Laisse des blocks tomber au dessus ? just changed erase="yes" * (longueur 1, hauteur (profonfeur), replicats) */ EntityPlayerLocal epl = player as EntityPlayerLocal; epl.cameraTransform.SendMessage("ShakeBig"); yield return(new WaitForSeconds(1f)); BlockSetter setter = new BlockSetter(options.OptionBlock); Vector3 direction = Vectors.Copy(place.direction); direction.y = 0; direction = direction.normalized; Vector3i start = Geo3D.Surface(place.ipos); for (int k = 0; k < options.OptionShape.shape.z; k++) { Vector3 kdirection = direction + Vectors.Float.Randomize(GameManager.Instance.World.GetGameRandom(), 0.2f); // IntLine traj = new IntLine(start, direction); //east IEnumerable <Vector3i> segment = IntLine.Segment(Vectors.ToFloat(start), kdirection, 0, options.OptionShape.shape.x); Vector3i prev = new Vector3i(); bool hasprev = false; foreach (Vector3i where in segment) { Vector3i Swhere = Geo3D.Surface(where); setter.Apply(Swhere); if (hasprev) { for (int creuse = 1; creuse < options.OptionShape.shape.y; creuse++) { setter.Apply(prev + creuse * Vectors.Down); } } setter.Push(); start = Swhere; yield return(new WaitForEndOfFrame()); hasprev = true; prev = Swhere; } yield return(new WaitForSeconds(1f)); } }
public static IEnumerator Puit(EntityPlayer player, Emplacement place, OptionEffect options) { /// crache des rochers yield return(Cave(player, place, options)); // EffectsItem.SpawnParticle(place.position, "big_smoke");// warning !! yield return(new WaitForSeconds(0.1f)); string item = options.OptionItem.item; for (int k = 0; k < 4; k++) { Vector3 motion = Vectors.Float.Randomize(player.world.GetGameRandom(), 1f, 3 * Vectors.Float.UnitY); motion = motion.normalized * 5f; yield return(EffectsItem.spawnItemGhost(item, place.position + 3.5f * Vectors.Float.UnitY, motion)); yield return(new WaitForSeconds(2f)); } }
public static IEnumerator Chaos(Entity _player, Emplacement place, OptionEffect options) { // ca fait rien pr l'instant. essayer de yield les sous call plutot que de les startcoroutine ?? Vector3i inipos = place.ipos; for (int repeat = 0; repeat < 5; repeat++) { for (int clone = 0; clone < 10; clone++) { OptionEffect copy = options.Copy(); // FIXME: copy Place too () Vector3i rdm = new Vector3i(Random.Next(-20, 20), 0, Random.Next(-20, 20)); place.ipos = inipos + rdm; // [!}] in-place with past coroutine, should be ok (get pos at start, we reassign) copy.OptionShape.shape = new Vector3i(Random.Next(0, 3), Random.Next(2, 8), Random.Next(0, 3)); // copy["size"] = String.Format("{0},{1},{2}", Random.Next(0,3), Random.Next(2,8), Random.Next(0,3)); Zombiome.Routines.Start(Peak(_player, place, copy), "Chaos--Peak"); yield return(new WaitForSeconds(0.3f)); } yield return(new WaitForSeconds(4.0f)); } }
public static IEnumerator Rift(EntityPlayer player, Emplacement place, OptionEffect options) { /* * Laisse des blocks tomber au dessus ? just changed erase="yes" */ Vector3i offsetSurface = new Vector3i(0, options.OptionShape.offsetSurface, 0); EntityPlayerLocal epl = player as EntityPlayerLocal; epl.cameraTransform.SendMessage("ShakeBig"); yield return(new WaitForSeconds(1f)); // Vector3i shape = options.OptionShape.shape; /// (longueur, hauteur, largeur) BlockSetter setter = new BlockSetter(options.OptionBlock); Vector3i start = Geo3D.Surface(place.ipos); for (int k = 0; k < 3; k++) { // Vector3 direction = Vectors.Float.UnitX + Vectors.Float.Randomize(GameManager.Instance.World.GetGameRandom(), 0.1f); Vector3 direction = place.direction + Vectors.Float.Randomize(GameManager.Instance.World.GetGameRandom(), 0.1f); direction.y = 0; direction = direction.normalized; // IntLine traj = new IntLine(start, direction); //east IEnumerable <Vector3i> segment = IntLine.Segment(Vectors.ToFloat(start), direction, 1, 5); // skip 0 intersecting with the previous foreach (Vector3i where in segment) { Vector3i Swhere = Geo3D.Surface(where) + offsetSurface; setter.Apply(Swhere); setter.Apply(Swhere + Vectors.Up); setter.Apply(Swhere + 2 * Vectors.Up); setter.Push(); start = Swhere; yield return(new WaitForEndOfFrame()); } yield return(new WaitForSeconds(1f)); } }
public static IEnumerator Cave(EntityPlayer player, Emplacement place, OptionEffect options) { /// TODO: enumérer les colonnes et s'arreter à surface BlockSetter setter = new BlockSetter(options.OptionBlock); Vector3i shape = options.OptionShape.shape; Vector3i start = Geo3D.Surface(place.ipos); int depth = shape.y; Vector3 direction = Vectors.Float.UnitY; // cannot use negative, so positive and get(_k) ! IntLine colonne = new IntLine(Vectors.ToFloat(start), direction); // Debug.Log(String.Format("Cave: pos={0} start={1} dir={2} ground={3}", place.position, start, direction, ground)); for (int d = 0; d < depth; d++) { // Debug.Log(String.Format("cave {0} {1}", d, setter)); if (options.OptionShape.ground != "" && d == depth - 1) { setter.options.block = Block.GetBlockByName(options.OptionShape.ground, false); } Vector3i where = colonne.Get(-d); Vector3i dxy = new Vector3i(0, 0, 0); foreach (int p in SdtdUtils.EffectsGround.LR(shape.x)) { foreach (int q in SdtdUtils.EffectsGround.LR(shape.z)) { dxy.x = p; dxy.z = q; Printer.Log(20, "Cave Apply (d,p) =", d, p, "where, dxy=", where, dxy); setter.Apply(where + dxy); } } Printer.FLog(20, "cave Push {0} {1}", d, where); setter.Push(); } yield return(new WaitForEndOfFrame()); }
public static IEnumerator RadiatedGhost(EntityPlayer player, Emplacement place, OptionEffect options) { options.OptionEntity.entity = "zombieMoeGhost"; options.OptionEntity.buff = "buffZBRadiating"; yield return(SpawnAndbuff(player, place, options)); }
public static IEnumerator FireGhost(EntityPlayer player, Emplacement place, OptionEffect options) { options.OptionEntity.entity = "animalChickenGhostV2"; options.OptionEntity.buff = "buffZbesRFireEst"; yield return(SpawnAndbuff(player, place, options)); }
/* * public static string Get(IDictionary<string, string> dico, string key, string def) { // UTILS * if (dico.ContainsKey(key)) return dico[key]; * return def; * } */ public static IEnumerator Peak(Entity player, Emplacement place, OptionEffect options) { Vector3i offsetSurface = new Vector3i(0, options.OptionShape.offsetSurface, 0); Vector3i pos = Geo3D.Surface(place.ipos) + Vectors.Up + offsetSurface; Vector3i shape = options.OptionShape.shape; float pace = options.OptionShape.pace; Block air = Block.GetBlockByName("air", false); // The air instance could prolly be shared ... Block blk = options.OptionBlock.block; BlockSetter setter = new BlockSetter(options.OptionBlock); Printer.Log(20, "Peak (position/pos=Surface+Up):", place.ipos, pos); Printer.Log(20, " (blk/pace/shape)", options.OptionBlock.block, options.OptionShape.pace, options.OptionShape.shape); Printer.Log(20, " setter (avB/avE,elastic):", options.OptionBlock.avoidBlock, options.OptionBlock.avoidEntity, options.OptionBlock.elastic); // Start at -1 only if air below for (int h = 0; h < shape.y; h++) { foreach (int e in LR(shape.x)) { foreach (int n in LR(shape.z)) { Vector3i where = new Vector3i(pos.x + e, pos.y + h, pos.z + n); setter.Apply(where); } setter.Push(); yield return(new WaitForSeconds(pace)); } // } if (options.OptionShape.reverse == "") { yield break; } // unset if exists options.OptionBlock.block = air; options.OptionBlock.avoidBlock = false; // protected by testing blk.blockID, and preventing us from actually deleting ! setter = new BlockSetter(options.OptionBlock); // IEnumerable<int> heights = Enumerable.Range(0, shape.y-1); IEnumerable <int> heights = Enumerable.Range(0, shape.y); if (options.OptionShape.reverse.Contains('U')) { } else { heights = Enumerable.Reverse(heights); } foreach (int h in heights) // when destroyed from below, collapse => destroy top to bottom { foreach (int e in LR(shape.x)) { foreach (int n in LR(shape.z)) { Vector3i where = new Vector3i(pos.x + e, pos.y + h, pos.z + n); BlockValue existing = GameManager.Instance.World.GetBlock(where); if (existing.type == blk.blockID) // only erase the type I just inserted { setter.Apply(where); // TODO: reverse once option // yield return new WaitForSeconds(sleep); } } } if (!options.OptionShape.reverse.Contains('O')) /// not once: update progressively { setter.Push(); yield return(new WaitForSeconds(pace)); } } }