You can read and reply to posts and download all mods without registering.
We're an independent and non-profit fan-site. Find out more about us here.
// Script configurationconst COMBINE_THRESHOLD = 250; // 250 works well for damage combiningconst DMG_ANIM_TIME = 500;const DMG_MAX_NUMS = 8;const DMG_HUD_CON = "zbDmgCon";// working variableslocal _numList = [];local xRef = int_ref();local yRef = int_ref();local xNum = 0;local yNum = 0;local t = 0;local iter = 0;local numObj = {};local numPurge = 0;// --------------------------------------------------------------------------------class damageNumbers extends SqRootScript { function OnDamage() { local i, ai, hudObj, height, pos, num, lastDamage; local m = message(); local AIHeights = [ ["Assassin", 7.22], ["Human", 7.22], ["Midwife", 7.27], ["Protocol Droid", 6.72], ["Training Droid", 6.72], ["Once-Grunts", 7.42], ["Big Droids", 6.88], ["Rumbler", 8.61], ["SHODAN", 8.07] ]; // only display numbers for damage player caused if (!Link.AnyExist("~CulpableFor", m.culprit, "Player")) { return; } // ensure overlay manager exists in current map if (ObjID(DMG_HUD_CON)) { hudObj = ObjID(DMG_HUD_CON); } else { hudObj = Object.Create("Marker"); Object.SetName(hudObj, DMG_HUD_CON) Property.Set(hudObj, "Scripts", "Script 0", "zbNumHudControl"); } // handle damage stacking and multiple damage sources on same projectile lastDamage = 0; if (ShockGame.SimTime() - (GetData("LastDmgTime") || 0) <= COMBINE_THRESHOLD) { for (i = _numList.len() - 1; i >= 0; i--) { if (_numList[i].obj == self) { lastDamage = _numList.remove(i).text.tointeger(); break; } } } SetData("LastDmgTime", ShockGame.SimTime()); // create damage number num = {obj = self, state=0, text=(m.damage + lastDamage).tostring(), pos=vector(), startTime=ShockGame.SimTime(), xOffset=0, yOffset=0, xArc=0}; pos = Object.Position(self); height = 0; // no way to get raw creature height or bounding box, so look up in a table // (this is for human-sized AIs only; smaller AIs just use the object center) foreach (ai in AIHeights) { if (Object.InheritsFrom(self, ai[0])) { height = ((ai[1] * (HasProperty("CretScale") ? GetProperty("CretScale") : 1)) / 2) * 0.5; } } num.pos = vector(pos.x, pos.y, pos.z + height); // add to render list _numList.push(num); if (_numList.len() > DMG_MAX_NUMS) { _numList.remove(0); } SendMessage(hudObj, "Show"); }}// --------------------------------------------------------------------------------// HUD controllerclass zbNumHudControl extends SqRootScript { function OnShow() { ShockOverlay.AddHandler(dmgOverlay); } function OnEndScript() { clobberAll(); } function destructor() { clobberAll(); } function clobberAll() { ShockOverlay.RemoveHandler(dmgOverlay); _numList = []; }}// --------------------------------------------------------------------------------// Display damage numbers in HUDclass dmgOverlayClass extends IShockOverlayHandler { function DrawHUD() { ShockOverlay.SetCustomFont(0, "metafont", "intrface\\"); ShockOverlay.SetFont(2); numPurge = -1; for (iter = 0; iter < _numList.len(); iter++) { numObj = _numList[iter]; if (numObj.state == 0) { ShockOverlay.GetStringSize(numObj.text, xRef, yRef); numObj.xOffset = xRef.tointeger() / 2; numObj.yOffset = yRef.tointeger(); numObj.xArc = Data.RandFltNeg1to1(); numObj.state = 1; } if (numObj.state == 1) { t = (ShockGame.SimTime() - numObj.startTime).tofloat() / DMG_ANIM_TIME; if (t < 1) { if (ShockOverlay.WorldToScreen(numObj.pos, xRef, yRef)) { xNum = xRef.tointeger() - numObj.xOffset; numObj.xOffset += numObj.xArc; //yNum = (yRef.tointeger() - yOffset) - sqrt(1-(--t)*t) * 25; yNum = (yRef.tointeger() - numObj.yOffset) - (1 - ((1 - t) * (1 - t))) * 30; ShockOverlay.SetTextColor(0, 0, 0); ShockOverlay.DrawString(numObj.text, xNum + 1, yNum + 1); ShockOverlay.SetTextColor(250 - 70 * t, 20, 20); ShockOverlay.DrawString(numObj.text, xNum, yNum); } } else { numObj.state = 2; } } else { numPurge = iter; } } // clean up finished slots if (numPurge > -1) { _numList = _numList.slice(numPurge + 1); if (_numList.len() == 0) { ShockOverlay.RemoveHandler(dmgOverlay); } } }}// This must follow the class definitiondmgOverlay <- dmgOverlayClass();
Speaking of which, for these sort of things is it the norm for the killing blow to display the potential damage, or the actual damage?Like, should dropping a nuke on an earthworm display "-100000000", or "-1"?
already put way more effort into this than I ever thought I would.