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 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 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 IEnumerator<Emplacement> Get(Vector3 position) { int iniy = (int) Math.Floor(position.y); IEnumerator<Vector3> pos = positions.Get(position); while(true) { string valid = ""; /* Extra point near or at player. NB: adds an extra yield */ if (rate_around > 0) { float u = Zombiome.rand.RandomFloat; if (u <= rate_around) { float ray = (u <= rate_at) ? 1f : 5f; yield return Emplacement.At( player.GetPosition() + Vectors.Float.Randomize(Zombiome.rand, ray), directions.Generate(pos.Current) ); } } /* Basic point */ bool continuing = pos.MoveNext(); // false if forward failed if (! continuing) { // Printer.Print("Placer.Get(): stop iteration"); yield break; } int th = GameManager.Instance.World.GetTerrainHeight((int) Math.Floor(pos.Current.x), (int) Math.Floor(pos.Current.z)); if (th == 0) { // Printer.Print("Placer.Get(): Chunk not loaded at", pos.Current); // Printer.Print(" position", position, "->", pos.Current); valid = "th=0"; } // Vector3 where = (this.AtSurface) ? Geo3D.Surface(pos.Current, iniy) : pos.Current; Vector3 where = (this.AtSurface) ? Geo3D.Surface(pos.Current, th) : pos.Current; /* Altitude check */ // if (Math.Abs(th - where.y) > 60) valid = String.Format("y={0} / th={1} < 60", where.y, th); // initial surface if (where.y > th + pOffSurface) valid = String.Format("Surface Offset y={0} / th={1} > pD = {2}", where.y, th, pOffSurface); // initial surface if (where.y < th - nOffSurface) valid = String.Format("Surface Offset y={0} / th={1} < nD = 60", where.y, th, nOffSurface); // initial surface if (where.y <= 1) valid = "y<1"; if (where.y >= 255) valid = "y>254"; // TODO: just stop if too far from player (eg teleport) or Zone center Emplacement place = Emplacement.At(where, directions.Generate(pos.Current)); if (valid.Length > 0) place.Invalid(valid); yield return place; } }
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 Entity SpawnEntity(Entity player, Emplacement place, Options options) { return(Spawn(place.position, options.entity)); }
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 void spawnItem(EntityPlayer player, Emplacement place, Options options) { spawnItem(player, options.item); }
public static void setBlockAt(Emplacement place, string block, Func <Vector3i, Block, int> setter) { setter(place.ipos, Block.GetBlockByName(block, false)); }
/* * 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)); } } }