/// <summary> /// Constructor /// </summary> public ModifyWindow(Backend.IHandleEvent parent, SpriteBatch spriteBatch, ContentManager content, Rectangle displayRect, Backend.Item item) : base(parent, spriteBatch, content, displayRect) { _item = item; AddChild(_name = new TextInput(this, _spriteBatch, _content, new Rectangle(_displayRect.Left + 5, _displayRect.Top + 5, _displayRect.Width - 15, 25), "Name:", _item.name, "This is the name used for the item.", 20, true)); _properties = new List<NumberEntry>(); int i = 0; foreach (Backend.ItemEffect effect in _item.effects) { AddChild(new NumberEntry(this, _spriteBatch, _content, new Rectangle(_displayRect.Left + 5, _displayRect.Top + 35 + i * 30, (_displayRect.Width - 10) / 2 - 10, 25), effect.property.ToString(), effect.effect, "Click to remove ability", 2, false)); ++i; } AddChild(new Button(this, _spriteBatch, _content, new Rectangle(_displayRect.Left + (_displayRect.Width - 100) / 2, _displayRect.Top + _displayRect.Height - 45, 100, 30), "Ok", (int)Backend.Buttons.Close, false)); }
/// /// <summary> /// Handle events from UIElements and/or backend objects /// </summary> /// <param name="DownStream"></param> /// <param name="eventID">The ID of the event</param> /// <param name="data">The parameters needed for that event</param> public override void HandleEvent(bool DownStream, Events eventID, params object[] data) { switch (eventID) { // Client: Player used item/ability // Map: NPC / Monster used item/ability case Backend.Events.ActivateAbility: { Actor actor = (Actor)data[0]; int id = (int)data[1]; // Use Item from inventory if (id < 0) { actor.Items(-id).UseItem(); // 2 Events: // 1. Item entfernen bzw. ausrüsten _parent.HandleEvent(false, Backend.Events.ActivateAbility, actor.id, id); // 2. Statistiken anpassen _parent.HandleEvent(false, Events.ChangeStats, actor.id, actor); // Update data on client } else { actor.mana -= actor.abilities[id - 1].cost; actor.abilities[id - 1].currentCool = actor.abilities[id - 1].cooldown * 7; switch (actor.abilities[id - 1].element) { case AbilityElement.Charm: _parent.HandleEvent(false, Events.FireProjectile, actor.id, AbilityElement.Charm); break; case AbilityElement.Fire: _parent.HandleEvent(false, Events.FireProjectile, actor.id, AbilityElement.Fire); break; case AbilityElement.Health: actor.health = Math.Min(actor.maxHealth, actor.health + actor.abilities[id - 1].intensity); break; case AbilityElement.HealthReg: actor.health = Math.Min(actor.maxHealth, actor.health + actor.abilities[id - 1].intensity); break; case AbilityElement.Ice: _parent.HandleEvent(false, Events.FireProjectile, actor.id, AbilityElement.Ice); break; case AbilityElement.ManaReg: break; case AbilityElement.Scare: _parent.HandleEvent(false, Events.FireProjectile, actor.id, AbilityElement.Scare); break; case AbilityElement.Stun: _parent.HandleEvent(false, Events.FireProjectile, actor.id, AbilityElement.Stun); break; } _parent.HandleEvent(false, Events.ChangeStats, actor.id, actor); // Update data on client _parent.HandleEvent(false, Backend.Events.ActivateAbility, actor.id, id); } } break; // Client: Animation finished playing => Re-Enable Actor, continue game case Backend.Events.FinishedAnimation: int FinishedID = (int)data[0]; if (_map.actors.Count >= FinishedID) { Activity FinishedActivity = (Activity)data[1]; switch (FinishedActivity) { case Activity.Die: if (_map.actors[FinishedID] is Enemy) { if (_map.actors[FinishedID].tile.enabled) { ((ActorTile)_map.actors[FinishedID].tile).enabled = false; ((ActorTile)_map.actors[FinishedID].tile).DropItems(); if (_map.actors[FinishedID].gold > 0) { ItemTile tile = new ItemTile(((FloorTile)(_map.actors[FinishedID].tile.parent))); Backend.Item item = new Backend.Item(tile, Backend.ItemType.Gold, "", null, _map.actors[FinishedID].gold); item.value = _map.actors[FinishedID].gold; tile.item = item; ((FloorTile)(_map.actors[FinishedID].tile.parent)).Add(tile); } _parent.HandleEvent(false, Events.SetItemTiles, _map.actors[FinishedID].tile, ((FloorTile)(_map.actors[FinishedID].tile.parent)).itemTiles); } } else { _parent.HandleEvent(false, Events.KillActor, FinishedID, _map.actors[FinishedID].tile.coords, 0, 0); } break; default: _map.actors[FinishedID].locked = false; break; } } break; case Backend.Events.TrapActivate: { Backend.Coords coords = (Coords)data[0]; if ((_map[coords].trap.status == TrapState.On) && (((_map[coords].hasEnemy) || (_map[coords].hasPlayer)) && (!_map[coords].firstActor.isDead))) { _TrapDamage(coords); } _parent.HandleEvent(false, Events.TrapActivate, coords, _map[coords].trap.status); } break; case Backend.Events.EndGame: map.Save("savedroom" + map.id + ".xml"); File.WriteAllText("save\\auto\\GameData", "room" + map.id.ToString() + ".xml"); break; case Backend.Events.TileEntered: { int id = (int)data[0]; if (id < _map.actors.Count) { _map.actors[id].locked = false; Direction dir = (Direction)data[1]; Backend.Coords target = _map.actors[id].tile.coords; // Pickup any items while (_map[target.x, target.y].hasTreasure) { _parent.HandleEvent(false, Events.PlaySound, SoundFX.Pickup); //SoundEffect pick items _parent.HandleEvent(false, Events.ShowMessage, ((_map.actors[id] is Player) ? "You found " : _map.actors[id].name + " found ") + _map[target.x, target.y].firstItem.item.name + " ."); if (_map.actors[id] is Player) _parent.HandleEvent(false, Events.ActorText, _map[target].firstActor.id, target, "Found " + _map[target.x, target.y].firstItem.item.name, Color.DarkGreen); _map[target.x, target.y].firstItem.item.Pickup(_map.actors[id]); _map[target.x, target.y].Remove(_map[target.x, target.y].firstItem); } // Apply trap damage if (((_map[target.x, target.y].hasTrap) && _map[target.x, target.y].trap.status == TrapState.On) && !(_map.actors[id] is NPC)) { _TrapDamage(target); } if (_map.actors[id] is Player) { //Checkpoint - save by entering if ((_map[target.x, target.y].hasCheckpoint) && (!_map[target.x, target.y].checkpoint.visited)) { _parent.HandleEvent(false, Events.PlaySound, SoundFX.Checkpoint);//SoundEffect checkpoint _map[target.x, target.y].checkpoint.visited = true; _map.actors[id].health = _map.actors[id].maxHealth; _map.actors[id].mana = _map.actors[id].maxMana; if (_map.actors[id].lives == -1) _map.actors[id].lives = 3; if (_map[target.x, target.y].checkpoint.bonuslife > 0) _map.actors[id].lives += (int)_map[target.x, target.y].checkpoint.bonuslife; _map.actors[id].lastCheckpoint = _map.id; _map.actors[id].checkPointCoords = new Coords(target.x, target.y); _map.Save("savedroom" + _map.id + ".xml"); _parent.HandleEvent(false, Events.ActorText, _map[target].firstActor.id, target, "Checkpoint", Color.DarkOliveGreen); Regex regex = new Regex(@"\d+"); _parent.HandleEvent(false, Events.ShowMessage, "Checkpoint reached (" + _map.actors[id].lives.ToString() + " lives remaining)"); _parent.HandleEvent(false, Events.Checkpoint, id); } // Trigger floor switches if (_map[_map.actors[id].tile.coords.x, _map.actors[id].tile.coords.y].hasTarget) { _parent.HandleEvent(false, Backend.Events.AnimateActor, id, Activity.Talk); //_mainmap2.HandleEvent(true, Backend.Events.AnimateActor, id, Activity.Talk); _parent.HandleEvent(false, Events.GameOver, true); } // Apply teleporter (move to next room) if (_map[target.x, target.y].hasTeleport) { HandleEvent(true, Backend.Events.ChangeMap, ((TeleportTile)_map[target.x, target.y].teleportTile).nextRoom, ((TeleportTile)_map[target.x, target.y].teleportTile).nextPlayerPos); } } } } // Allow to choose next turn break; case Backend.Events.Attack: { int id = (int)data[0]; Direction dir = (Direction)data[1]; Backend.Coords target = Map.DirectionTile(_map.actors[id].tile.coords, dir); if (_map.CanMove(_map.actors[id].tile.coords, dir)) { _parent.HandleEvent(false, Backend.Events.Attack, id, dir); _CombatDamage(id, _map[target.x, target.y].firstActor.id); } } break; case Backend.Events.ExplodeProjectile: { _map[((ProjectileTile)data[0]).coords].Remove((ProjectileTile)data[0]); if (data[2] != null) { Actor actor = data[2] as Actor; int damage = 20 - actor.armor + (5 - _random.Next(10)); if (damage > 0) { actor.health -= damage; if (actor is Player) { _parent.HandleEvent(false, Events.FloatText, actor.tile.coords, damage.ToString(), Color.DarkRed); _parent.HandleEvent(false, Events.DamageActor, actor.id, actor.tile.coords, actor.health, damage); } } } _parent.HandleEvent(false, eventID, data); } break; case Backend.Events.MoveProjectile: if (data[0] == null) { _parent.HandleEvent(false, Backend.Events.AddProjectile, ((FloorTile)data[1]).coords, (Direction)data[2], new ProjectileTile((FloorTile)data[1], (Direction)data[2])); } else { _parent.HandleEvent(false, Backend.Events.MoveProjectile, ((ProjectileTile)data[0]).id, (Coords)data[1]); } break; case Backend.Events.FinishedProjectileMove: ((ProjectileTile)data[0]).NextTile(true); break; case Backend.Events.Shop: _parent.HandleEvent(false, Events.Shop, (Actor)data[1], (Actor)data[0]); break; case Backend.Events.Dialog: Player player = ((Player)data[1]); //player string texttodisplay = ""; int queststodo = 0; if (player.quests.Length <= 0) { texttodisplay += "Welcome, hero. I offer you this quest:\n\n"; // Quest nq = new Quest(Quest.QuestType.CollectItems, "Find, buy or steal a new item!", 100, null, player.inventory.Count + 1); // player.AddQuest(nq); // texttodisplay += nq.text; } else { int exp = player.exp; player.UpdateQuests(); //update quests and get reward foreach (Quest q in player.quests) { texttodisplay += q.text; /* if (q.Completed) texttodisplay = "You successfully performed my quest. I grant you " + q.xp.ToString() + " experience points."; else { texttodisplay = "I am still waiting for you to perform my quest:\n\n" + q.text; queststodo++; } */ } if (player.exp - exp > 0) _parent.HandleEvent(false, Events.ActorText, player.id, player.tile.coords, "+" + (player.exp - exp).ToString() + " Exp", Color.Gold); // Update data on client while (player.exp > player.expNeeded) { player.LevelUp(); _parent.HandleEvent(false, Events.ChangeStats, player.id, player); // Update data on client } } GenericDialog(((Actor)data[1]).id, ((Actor)data[0]).id, texttodisplay); break; case Backend.Events.MoveActor: { if ((data.Length > 1) && (_map.actors.Count >= (int)data[0]) && (!_map.actors[(int)data[0]].locked)) { int id = (int)data[0]; _map.actors[id].locked = true; Direction dir = (Direction)data[1]; Backend.Coords target = Map.DirectionTile(_map.actors[id].tile.coords, dir); _map.actors[id].direction = dir; if (((FloorTile)_map.actors[id].tile.parent).hasTrap) { if (((FloorTile)_map.actors[id].tile.parent).trap.status == TrapState.Disabled) ((FloorTile)_map.actors[id].tile.parent).trap.status = TrapState.NoDisplay; _parent.HandleEvent(false, Backend.Events.ChangeTrapState, _map.actors[id].tile.coords.x, _map.actors[id].tile.coords.y, TrapState.NoDisplay); } Actor a = _map[target.x, target.y].firstActor; if ((a is NPC) && (_map.actors[id] is Player)) { (a as NPC).Interact(_map.actors[id]); } if ((a is Enemy || a is Player) && !(_map.actors[id] is NPC) // NPCs do not attack && (a.id != id) // Do not attack yourself && (!a.isDead) // Do not attack dead opponents && !((a is Player) && (!a.online)) // Do not attack offline players && !((a is Player) && (_map.actors[id] is Player)) // No Player vs Player ) { HandleEvent(true, Backend.Events.Attack, id, dir); } else { if ((_map[target].hasDoor) && (_map.actors[id] is Player) && (!_map[target].door.open)) { if (_map.actors[id].HasKey(_map.level)) { _map[target].door.open = true; _parent.HandleEvent(false, Events.ShowMessage, "You open the door using the key you fought for."); } else { _parent.HandleEvent(false, Events.ShowMessage, "The door is locked.\n It is likely a strong creature guards the key."); } } if (_map.CanMove(_map.actors[id].tile.coords, dir)) { Coords old = new Coords(_map.actors[id].tile.coords.x, _map.actors[id].tile.coords.y); _map.MoveActor(_map.actors[id], dir); _parent.HandleEvent(false, Backend.Events.MoveActor, id, dir, _map.actors[id].moveIndex, _map.actors[id].tile.coords, old); } else { _parent.HandleEvent(false, Backend.Events.RejectMove, id, dir, _map.actors[id].moveIndex, _map.actors[id].tile.coords, _map.actors[id].tile.coords); _map.actors[id].locked = false; } } } } break; case Backend.Events.Initialize: ReassignPlayer(); break; case Backend.Events.Pause: _paused = true; _parent.HandleEvent(true, Backend.Events.Pause); break; case Backend.Events.ContinueGame: if (!DownStream) _parent.HandleEvent(true, Backend.Events.ContinueGame, true); _paused = false; break; case Backend.Events.LoadFromCheckPoint: HandleEvent(false, Backend.Events.Pause); map.Save("room" + map.id + ".xml"); Coords targetCoords = map.actors[(int)data[0]].checkPointCoords; map.actors[(int)data[0]].lives--; map.actors[(int)data[0]].health = map.actors[(int)data[0]].maxHealth; if (map.id != map.actors[(int)data[0]].lastCheckpoint) { ChangeMap("room" + map.actors[(int)data[0]].lastCheckpoint.ToString() + ".xml", targetCoords); map.Save("room" + map.id + ".xml"); } else map.PositionActor(map.actors[(int)data[0]], targetCoords); HandleEvent(false, Backend.Events.Initialize, true); break; case Backend.Events.ChangeMap: // Load another map HandleEvent(false, Backend.Events.Pause); ChangeMap((string)data[0], (Coords)data[1]); ReassignPlayer(); break; case Backend.Events.NewMap: HandleEvent(false, Backend.Events.Pause); _map.ClearActors(); GenerateMaps(); map.Load("room1.xml", null, true); HandleEvent(false, Backend.Events.ContinueGame, true); break; case Backend.Events.ResetGame: _DeleteSavedRooms(); _map.ClearActors(); _map.Load("room1.xml", null, true); HandleEvent(false, Events.Initialize, true); break; } }