Jump to content
  • 0

ACT EDITOR: Mob Name & Element Script help


Karou

Question


  • Group:  Members
  • Topic Count:  1
  • Topics Per Day:  0.00
  • Content Count:  1
  • Reputation:   0
  • Joined:  06/08/19
  • Last Seen:  

Hello, i'm not sure if this is the right place to ask but is there anyone who has a script for putting mob name on top of the monster sprite on all layers and then putting the Element they're most vulnerable to- on top of the mobname?(refer to pic #1 for example)

or even just the Element the mob is most vulnerable to? (refer to pic #2 for example)

I did find a script made by Tokeiburu himself regarding putting mobname on top of the monster sprite on all layers, but i haven't found any clue about putting elemental vulnerability of the monster instead. So if anyone has an idea, it'd be much appreciated!

Screenshot 2024-12-10 020053.png

Screenshot 2024-12-10 020358.png

Link to comment
Share on other sites

2 answers to this question

Recommended Posts

  • 0

  • Group:  Members
  • Topic Count:  16
  • Topics Per Day:  0.00
  • Content Count:  696
  • Reputation:   721
  • Joined:  11/12/12
  • Last Seen:  

This was resolved through PMs a while back; here was the final script for anyone interested:

// Act Editor Script - v1.0.5.1
// By Tokeiburu
GrfColor textForeground = "0xffffff";
var fontType = "Minecraftia";
var fontSize = 14;
var fontBold = true;
var dataGrfName = @"C:\mobWithNames\data.grf";
var newGrfName = @"C:\mobWithNames\mobsWithName.grf";
var mobDbPath = @"C:\mobWithNames\mob_db.yml";
var attrFixDbPath = @"C:\mobWithNames\attr_fix.yml";
var jobnamePath = @"C:\mobWithNames\jobname.lub";
var npcIdentityPath = @"C:\mobWithNames\npcidentity.lub";
var oldEncoding = EncodingService.DisplayEncoding;
var displayMobNames = false;
var maxElementShown = 3;
var showFirstElementDamage = true;
//var elementTextColors = false;

// Fixed settings
var mobFolder = @"data\sprite\¸ó½ºÅÍ\";
//jobnamePath = @"C:\Gravity Ragnarok - Copy\data\luafiles514\lua files\datainfo\jobname.lub";
//npcIdentityPath = @"C:\Gravity Ragnarok - Copy\data\luafiles514\lua files\datainfo\npcidentity.lub";
//dataGrfName = @"C:\Gravity Ragnarok - Copy\data.grf";
//newGrfName = @"C:\test\mobsWithName.grf";
//mobDbPath = @"C:\Users\Tokei\Desktop\SVN\rathena4\db\re\mob_db.yml";
//attrFixDbPath = @"C:\Users\Tokei\Desktop\SVN\rathena4\db\re\attr_fix.yml";

var jobname = new JobnameLubData(jobnamePath, npcIdentityPath);

int[,,] attr_fix = new int[4, 10, 10];
StringBuilder b = new StringBuilder();
var ele2id = new Dictionary<string, int>();
ele2id["Neutral"] = 0;
ele2id["Water"] = 1;
ele2id["Earth"] = 2;
ele2id["Fire"] = 3;
ele2id["Wind"] = 4;
ele2id["Poison"] = 5;
ele2id["Holy"] = 6;
ele2id["Dark"] = 7;
ele2id["Ghost"] = 8;
ele2id["Undead"] = 9;

var id2ele = new Dictionary<int, string>();
foreach (var entry in ele2id)
	id2ele[entry.Value] = entry.Key;

try {
	EncodingService.DisplayEncoding = EncodingService.ANSI;
	int ival;
	string[] values;
	var mobId2ServerName = new Dictionary<int, string>();
	var mobId2ServerElement = new Dictionary<int, int>();
	var mobId2ServerElementLevel = new Dictionary<int, int>();
	
	{
		// Load the attr_fix file
		var parser = new YamlParser(attrFixDbPath);
		var body = parser.Output["Body"];
		
		foreach (var entry in body) {
			int level = Int32.Parse(entry["Level"]) - 1;
			
			foreach (var ele2id_entry in ele2id) {
				var element_name = ele2id_entry.Key;
				var element_id = ele2id_entry.Value;
				
				var def_elements = entry[element_name];
			
				foreach (ParserKeyValue def_ele in def_elements) {
					attr_fix[level, element_id, ele2id[def_ele.Key]] = Int32.Parse(def_ele.Value);
				}
			}
		}
	}
	
	{
		// Load the mob_db file
		var parser = new YamlParser(mobDbPath);
		var body = parser.Output["Body"];
		
		foreach (var entry in body) {
			int mobId = Int32.Parse(entry["Id"]);
			mobId2ServerName[mobId] = entry["Name"];
			
			int eleId = 0;
			int eleLevel = 0;
			
			if (entry["Element"] != null) {
				eleId = ele2id[entry["Element"]];
			}
			
			if (entry["ElementLevel"] != null) {
				eleLevel = Int32.Parse(entry["ElementLevel"]) - 1;
			}
			
			mobId2ServerElement[mobId] = eleId;
			mobId2ServerElementLevel[mobId] = eleLevel;
		}
	}
	
	Func<Act, string, int, Act> addNameAbove = (actI, display, offset) => {
		var pixels = new byte[256 * 20 * 4];
		BitmapSource bitmapSource = BitmapSource.Create(256, 20, 96, 96, PixelFormats.Bgra32, null, pixels, 256 * 4);
		var visual = new DrawingVisual();
		using (DrawingContext drawingContext = visual.RenderOpen()) {
			var ft = new FormattedText(display, CultureInfo.InvariantCulture, FlowDirection.LeftToRight,
				new Typeface(fontType), fontSize, new SolidColorBrush(textForeground.ToColor()));
			
			if (fontBold)
				ft.SetFontWeight(FontWeights.Bold);
			drawingContext.DrawImage(bitmapSource, new Rect(0, 0, 256, 20));
			drawingContext.DrawText(ft, new Point(2, 2));
		}
 
		var image = new DrawingImage(visual.Drawing);
		var im = new Image { Source = image };
		im.Measure(new Size(image.Width, image.Height));
		im.Arrange(new Rect(0.0, 0.0, image.Width, image.Height));
		im.UpdateLayout();
 
		var grfImage = GrfToWpfBridge.Imaging.ConvertToBitmapSource(im);
		var transparent = new GrfColor(0, 0, 0, 0);
 
		for (int i = 0; i < grfImage.NumberOfPixels; i++) {
			Buffer.BlockCopy((grfImage.Pixels[4 * i + 3] > 0x80 ? textForeground : transparent).ToBgraBytes(), 0, grfImage.Pixels, 4 * i, 4);
		}
 
		grfImage.Convert(GrfImageType.Indexed8); grfImage.Trim(); grfImage.Margin(2);
		Buffer.BlockCopy(GrfColor.Black.ToBgraBytes(), 0, grfImage.Palette, 2 * 4, 4);
 
		for (int y = 1; y < grfImage.Height - 1; y++) {
			for (int x = 1; x < grfImage.Width - 1; x++) {
				if (grfImage.Pixels[y * grfImage.Width + x] == 1) continue;
 
				if (grfImage.Pixels[(y - 1) * grfImage.Width + (x)] == 1 || grfImage.Pixels[(y + 1) * grfImage.Width + (x)] == 1 ||
					grfImage.Pixels[(y) * grfImage.Width + (x - 1)] == 1 || grfImage.Pixels[(y) * grfImage.Width + (x + 1)] == 1)
					grfImage.Pixels[y * grfImage.Width + x] = 2;
			}
		}
		
		act = actI;
		
		// Doesn't support Bgra32 only sprites
		if (act.Sprite.Palette == null) return act;
 
		var unused = act.Sprite.GetUnusedPaletteIndexes().ToList();
		if (unused.Count <= 1) return act;
		if (!act.Sprite.Palette.Contains(textForeground)) Buffer.BlockCopy(textForeground.ToBgraBytes(), 0, act.Sprite.Palette.BytePalette, 4 * unused[0], 4);
		if (!act.Sprite.Palette.Contains(GrfColor.Black)) Buffer.BlockCopy(GrfColor.Black.ToBgraBytes(), 0, act.Sprite.Palette.BytePalette, 4 * unused[1], 4);
 
		var colors = act.Sprite.Palette.Colors.ToList();
		var whiteIndex = (byte)colors.IndexOf(textForeground);
		var blackIndex = (byte)colors.IndexOf(GrfColor.Black);
 
		for (int i = 0; i < grfImage.NumberOfPixels; i++) {
			if (grfImage.Pixels[i] == 1) grfImage.Pixels[i] = whiteIndex;
			else if (grfImage.Pixels[i] == 2) grfImage.Pixels[i] = blackIndex;
		}
 
		var index = act.Sprite.InsertAny(grfImage);
		var max = 0;
 
		act.AnimationExecute(0, a => a.AllLayers(p => {
			if ((ival = ((int)(p.ScaleY * p.Height) / 2 - p.OffsetY)) > max)
				max = ival;
		}));
 
		max += 15;
 
		var layer = new Layer(index, grfImage) { OffsetY = -(max + fontSize / 2) + offset };
		ival = 0;
 
		foreach (var action in act) {
			// Don't show for the death animation
			if (ival >= 32 && ival < 40)
				continue;
 
			foreach (var frame in action) {
				frame.Layers.Add(layer);
			}
 
			ival++;
		}
 
		return act;
	};
	
	string displayName;
	int from = -1;
	var processed = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
 
	using (var dataGrf = new GrfHolder(dataGrfName))
	using (var outputGrf = new GrfHolder(newGrfName, GrfLoadOptions.New)) {
		int count = jobname.Id2Sprite.Count;
 
		TaskManager.DisplayTaskC("Adding text label", "Processing...", () => from / (float) count * 100f, isCancelling => {
			try {
				foreach (var mobEntry in jobname.Id2Sprite.OrderBy(p => p.Key)) {
					if (isCancelling()) return;
					
					var mobResourceName = mobEntry.Value;
					var mobId = mobEntry.Key;
					
					//b.AppendLine(mobId + "\t" + mobResourceName + "\t" + processed.Contains(mobResourceName));
					
					if (processed.Contains(mobResourceName)) {
						from++;
						continue;
					}
					
					if (mobId2ServerName.ContainsKey(mobId)) {
						displayName = mobId2ServerName[mobId];//.ToUpper();
						processed.Add(mobResourceName);
					}
					else {
						displayName = jobname.Id2Job[mobId].Replace("JT_", "").Replace("_", " ");//.ToUpper();
					}
					
					var actEntry = dataGrf.FileTable.TryGet(GrfPath.Combine(mobFolder, mobResourceName + ".act"));
					var sprEntry = dataGrf.FileTable.TryGet(GrfPath.Combine(mobFolder, mobResourceName + ".spr"));
					
					if (actEntry == null || sprEntry == null) {
						from++;
						continue;
					}
 
					var mobAct = new Act(actEntry, new Spr(sprEntry));
					
					StringBuilder e_builder = new StringBuilder();
					
					if (mobId2ServerName.ContainsKey(mobId)) {
						int eleLevel = mobId2ServerElementLevel[mobId];
						int eleId = mobId2ServerElement[mobId];
						var dmgElements = new Dictionary<int, int>();
						
						for (int i = 0; i < 9; i++) {
							dmgElements[i] = attr_fix[eleLevel, i, eleId];
						}
						
						int highest = -1;
						int max = maxElementShown;
						
						foreach (var dmgElement in dmgElements.OrderByDescending(p => p.Value)) {
							if (dmgElement.Value < highest)
								break;
							
							max--;
							
							if (max < 0) {
								e_builder.Append("...");
								break;
							}
							
							highest = dmgElement.Value;
							
							if (e_builder.Length == 0)
								e_builder.Append(id2ele[dmgElement.Key] + (showFirstElementDamage ? " (" + dmgElement.Value + "%)" : ""));
							else
								e_builder.Append(" - " + id2ele[dmgElement.Key]);
						}
						
						mobAct = addNameAbove(mobAct, e_builder.ToString(), 0);
						
						if (displayMobNames)
							mobAct = addNameAbove(mobAct, displayName, 15);
					}
					else {
						if (!displayMobNames) {
							from++;
							continue;
						}
						
						mobAct = addNameAbove(mobAct, displayName, 0);
					}
					
					MemoryStream actStream = new MemoryStream();
					MemoryStream sprStream = new MemoryStream();
 
					try {
						mobAct.SaveWithSprite(actStream, sprStream);
					}
					catch {
						from++;
						continue;
					}
					
					outputGrf.Commands.AddFile(actEntry.RelativePath, actStream);
					outputGrf.Commands.AddFile(sprEntry.RelativePath, sprStream);
 
					if (from % 200 == 0) {
						GC.Collect();
						outputGrf.QuickSave();
						outputGrf.Reload();
					}
 
					from++;
				}
			}
			catch (Exception err) {
				ErrorHandler.HandleException(err);
			}
			finally {
				outputGrf.QuickSave();
				from = count;
			}
		});
		
		//ErrorHandler.HandleException(b.ToString());
	}
}
catch (Exception err) {
	ErrorHandler.HandleException(err);
}
finally {
	EncodingService.DisplayEncoding = oldEncoding;
}

 

Edited by Tokei
  • Upvote 2
  • Like 1
Link to comment
Share on other sites

  • 0

  • Group:  Forum Moderator
  • Topic Count:  48
  • Topics Per Day:  0.01
  • Content Count:  941
  • Reputation:   125
  • Joined:  05/23/12
  • Last Seen:  

U can add the Element to the Mobname it should be \n to add a new line. U need Source modification.

 

Rynbef~

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...