Example #1
0
		public CharacterWorldLogin(Character c)
			: base(0x71, 28) {
			string mapname = Map.GetClientName(c.LastPoint.Map.Name);
			Write((int)c.Serial.Value);
			Write(mapname, Core.Conf.General.GetInt("MaxMapNameClientLength"));
			Write((int)Core.Connector.Listener.IPs[0].Address);
			Write((short)Core.Connector.Listener.Ports[0]);
		}
Example #2
0
		public CharacterResponseWorldLogin(Character c)
			: base(0x71, 28) {
			string mapname = Map.GetClientName(c.Status.Location.Map.Name);
			Write((uint)c.WorldID.ID);
			Write(mapname, Global.MAP_NAME_LENGTH_EXT);
			Write((int)Core.Connector.Listener.IPs[0].GetAddress());
			Write((short)Core.Connector.Listener.Ports[0]);
		}
Example #3
0
		public WorldWalkOK(Character c)
			: base(0x87, 11) {
			Write((int)DateTime.Now.Ticks);
			Write(c.Location.Point, c.TargetLocation, new Point2D(8, 8));
		}
Example #4
0
		/*==========================================
		 * Fetches a random mobID
		 * type: Where to fetch from:
		 * 0: dead branch list
		 * 1: poring list
		 * 2: bloody branch list
		 * flag:
		 * &1: Apply the summon success chance found in the list (otherwise get any monster from the db)
		 * &2: Apply a monster check level.
		 * &4: Selected monster should not be a boss type
		 * &8: Selected monster must have normal spawn.
		 * lv: Mob level to check against
		 *------------------------------------------*/
		public static int GetRandomMobID(Character character, int type, int flag, int lv) {
			int mobID = 0;
			// TODO: implement me q.q
			/*
			do {
				if (type > 0)
					class_ = summon[type].class_[rand()%summon[type].qty];
				else //Dead branch
					class_ = rand() % MAX_MOB_DB;
				mob = mob_db(class_);
			} while ((mob == mob_dummy ||
				mob_is_clone(class_) ||
				(flag&1 && mob->summonper[type] <= rand() % 1000000) ||
				(flag&2 && lv < mob->lv) ||
				(flag&4 && mob->status.mode&MD_BOSS) ||
				(flag&8 && mob->spawn[0].qty < 1)
			) && (i++) < MAX_MOB_DB);

			if(i >= MAX_MOB_DB)  // no suitable monster found, use fallback for given list
				class_ = mob_db_data[0]->summonper[type];
			*/
			return mobID;
		}
Example #5
0
		private static Monster SpawnOnceSub(Character character, Location loc, string name, int mobID) {
			// Create new world object based on mobID
			Monster mob = new Monster(new DatabaseID(mobID, EDatabaseType.Mob));
			// Search free cell to spawn, if no given
			Point2D spawnPoint = loc.Point;
			if (character != null && (spawnPoint.X < 0 || spawnPoint.Y < 0)) {
				// if none found, pick random position on map
				if (loc.Map.SearchFreeCell(character, ref spawnPoint, 1, 1, 0) == false) {
					if (spawnPoint.X <= 0 || spawnPoint.Y <= 0 || loc.Map.CheckCell(spawnPoint, ECollisionType.Reachable) == false) {
						// Failed to fetch random spot on the whole map?
						if (loc.Map.SearchFreeCell(null, ref spawnPoint, -1, -1, 1) == false) {
							ServerConsole.ErrorLine("SpawnSub: Failed to locate spawn pos on map " + loc.Map.Name);
							return null;
						}
					}
				}
			}

			mob.Location = new Location(loc.Map.ID, spawnPoint);
			mob.Name = name;
			mob.Class = (short)mobID;

			// mob_parse_dataset here; check for tiny/large, event and so on

			// TODO: takeover of special_state AI ect; need mob_parse_dataset before
			//		 and place in Monster class to store it (look @ eA mob_data)

			mob.ViewData = WorldObjectViewData.GetViewData(mob.Database, mobID);
			mob.Status = new WorldObjectStatus(mob);
			mob.BaseStatus = new WorldObjectStatus(mob);
			mob.StatusChange.Clear();

			return mob;
		}
Example #6
0
		public CharacterResponseNewData(Character c)
			: base(0x6d) {
			c.ToStream(Writer);
		}
Example #7
0
		private uint CalculateBasePcMaxSP(Character character, WorldObjectStatus status) {
			return 0;
		}
Example #8
0
		/// <summary>Executes the warp action.</summary>
		/// <param name="target">Target for the warp.</param>
		public virtual void OnWarp(Character target) {
			// TODO: basic warp
		}
Example #9
0
		/// <summary>
		/// Callback for executing an action (attack/sit/stand) to a target (ID)
		/// </summary>
		/// <param name="character"></param>
		/// <param name="action"></param>
		/// <param name="id"></param>
		private static void Callback_ActionRequest(Character character, byte action, int id) {
			// TODO: check for dead player
			// TODO: check for trickdead, autocounter or bladestop (no action available)

			character.StopWalking(0x1);
			character.StopAttack();

			// For disguise
			if (id < 0 && -id == character.AccountID) {
				id = (int)character.AccountID;
			}

			switch (action) {
				case 0x0: // Attack once
				case 0x7: // Attack continue
					if (character.CantAct() == false || (character.StatusChange.Option & EStatusOption.Hide) > 0) {
						return;
					}
					EStatusOption badOptions = (EStatusOption.Wedding | EStatusOption.Xmas | EStatusOption.Summer);
					if ((character.StatusChange.Option & badOptions) > 0) {
						return;
					}

					// TODO: basilica
					// TODO: freecast check

					character.ResetInvisibleTimer();
					character.Attack(id, (action != 0x0));
					break;
				case 0x02: // sitdown
					/*
					if (battle_config.basic_skill_check && pc_checkskill(sd, NV_BASIC) < 3) {
						clif_skill_fail(sd, 1, 0, 2);
						break;
					}
					*/

					if (character.IsSit() == true) {
						// Bugged client? Just refresh them
						World.Send(new WorldUnitSitStand(character, true), character, ESendTarget.Area);
						return;
					}

					if (Timer.IsValid(character.ActiveSkillTimer) == true || character.StatusChange.Option1 != EStatusOption1.None) {
						break;
					}
					/*
					if (sd->sc.count && (
						sd->sc.data[SC_DANCING] ||
						(sd->sc.data[SC_GRAVITATION] && sd->sc.data[SC_GRAVITATION]->val3 == BCT_SELF)
					)) //No sitting during these states either.
						break;
					*/
					character.SetSit();
					//skill_sit(sd, 1);
					World.Send(new WorldUnitSitStand(character, true), character, ESendTarget.Area);
					break;
				case 0x03: // standup
					if (character.IsSit() == false) {
						World.Send(new WorldUnitSitStand(character, false), character, ESendTarget.Area);
						return;
					}
					character.SetStand();
					//skill_sit(sd, 0);
					World.Send(new WorldUnitSitStand(character, false), character, ESendTarget.Area);
					break;
			}

		}
Example #10
0
		public NewCharacterData(Character c)
			: base(0x6d) {
			c.ToStream(Writer);
		}
Example #11
0
		public static ECharacterCreationResult Create(Account account, string name, byte slot, byte str, byte agi, byte vit, byte int_, byte dex, byte luk, short hairColor, short hairStyle, out Character newChar) {
			newChar = null;

			if (name.Length > 24) {
				name = name.Substring(0, 24);
			}
			//name = name.Replace('\032', ' ').Replace('\t', ' ').Replace('\x0A', ' ').Replace('\x0D', ' ');

			if (
				(slot >= Global.MAX_SLOTS) ||
				(str + agi + vit + int_ + dex + luk != 6 * 5) ||
				(str < 1 || str > 9 || agi < 1 || agi > 9 || vit < 1 || vit > 9 || int_ < 1 || int_ > 9 || dex < 1 || dex > 9 || luk < 1 || luk > 9) ||
				(str + int_ != 10 || agi + luk != 10 || vit + dex != 10)
			) {
				return ECharacterCreationResult.CharCreationDenied; // invalid input
			}

			// Check for max character count on this account
			if (account.Chars.Count >= Global.MAX_SLOTS) {
				return ECharacterCreationResult.CharCreationDenied; // character account limit exceeded
			}
			// Check for existing char with this name
			if (Core.Database.Query("SELECT charID FROM `char` WHERE `name` = '{0}'", name.MysqlEscape()).Rows.Count > 0) {
				return ECharacterCreationResult.CharnameAlreadyExists;
			}
			// Check for existing char on this slot
			foreach (Character tmpChar in account.Chars.Values) {
				if (tmpChar.Status.Slot == slot) {
					return ECharacterCreationResult.CharCreationDenied;
				}
			}

			// TODO: this has to be in CharacterDatabaseStatus, nor?
			//		 CharacterDatabaseData represents the character in the character server
			//		 so..
			newChar = new Character(DatabaseID.Zero, false);
			newChar.Parent = account;
			newChar.Status.Name = name;
			newChar.Status.Slot = slot;
			newChar.Status.Zeny = Config.StartZeny;
			newChar.Status.Str = str;
			newChar.Status.Agi = agi;
			newChar.Status.Dex = dex;
			newChar.Status.Vit = vit;
			newChar.Status.Int = int_;
			newChar.Status.Luk = luk;
			newChar.Status.HPMax = newChar.Status.HP = (40 * (100 + vit) / 100);
			newChar.Status.SPMax = newChar.Status.SP = (11 * (100 + int_) / 100);
			newChar.Status.HairStyle = hairStyle;
			newChar.Status.HairColor = hairColor;
			newChar.Status.SavePoint = new Location(Mapcache.GetID(Config.StartMap), Config.StartMapX, Config.StartMapY);
			newChar.Status.Location = new Location(newChar.Status.SavePoint.Map.ID, newChar.Status.SavePoint.Point.X, newChar.Status.SavePoint.Point.Y);

			// Save it
			CharacterDatabaseData status = newChar.Status;
			string query =
				string.Format(
					"INSERT INTO `char` (" +
						"`accountID`, `slot`, `name`, `zeny`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hpMax`, `hp`," +
						"`spMax`, `sp`, `hair`, `hairColor`, `lastMap`, `lastX`, `lastY`, `saveMap`, `saveX`, `saveY`" +
					") VALUES (" +
						"{0}, {1}, '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}', '{11}'," +
						"'{12}', '{13}', '{14}', '{15}', '{16}', '{17}', '{18}', '{19}', '{20}', '{21}'" +
					")"
					,
					account.WorldID.ID, slot, name.MysqlEscape(), status.Zeny, status.Str, status.Agi, status.Vit,
					status.Int, status.Dex, status.Luk, status.HPMax, status.HP, status.SPMax, status.SP,
					status.HairStyle, status.HairColor, status.Location.Map, status.Location.Point.X, status.Location.Point.Y,
					status.SavePoint.Map, status.SavePoint.Point.X, status.SavePoint.Point.X
				);
			Core.Database.Query(query);
			uint charID = (uint)Core.Database.GetLastInsertID();
			if (charID == 0) {
				// Failed to add character?
				return ECharacterCreationResult.CharCreationDenied;
			}
			// save Serial/CharID
			newChar.UpdateDatabaseID(charID, EDatabaseType.Char);
			newChar.WorldID = new WorldID(charID, EDatabaseType.Char);
			// Add it to account dictionary
			account.Chars.Add(newChar.WorldID, newChar);

			return ECharacterCreationResult.Success;
		}
Example #12
0
		public static Character Load(Account account, DataRow row) {
			Character c = new Character(DatabaseID.Zero, false);
			// Load basic character data
			c.Status = new CharacterDatabaseData(row);

			// Update WorldID (same as Serial/DatabaseID)
			c.WorldID = new WorldID(c.Status.Serial.ID, c.Status.Serial.Type);
			// Update location
			c.Location = c.Status.Location;
			// Update account
			c.Parent = account;

			return c;
		}
Example #13
0
		/// <summary>Executes the touch action.</summary>
		/// <param name="target">Target for the touch.</param>
		public virtual void OnTouch(Character target) {

		}
Example #14
0
		/// <summary>Executes the click action.</summary>
		/// <param name="target">Target for the click.</param>
		public virtual void OnClick(Character target) {

		}