Jump to content

Horrible Design Flaw - Protector Bots first shields Everything and only then Caster -reason found!


Purrfekshawn

Recommended Posts

Horrible Game Breaking Design Flaw - Protector Bots first shields Everything and only then Caster - reason found! The reason of this has been found, and since that requesting IMMEDIATE fix (as We're always Nice n.n, so Fix it #RITENOW!!!

 

Protector Bots first shields literally EVERYTHING - Other Bots, Seeker Drones, Acid Mortars, Incarnate Pets, the Demon, the Devil (also the whole list down)..., gracefully ignoring the only thing - its owner. It has been known for so long time, and now l looked in Dev files and found the actual reason of this Atrocious, Horrendous, Horrid code error:

 

It's located in "%CoHDevSourceFilesFolder%\coh-server-original-master\MapServer\ai\entaiCritterActivityCombat.c"

 

1835	Entity* aiCritterFindTeammateInNeed(Entity* e, AIVars *ai, F32 range, AIPowerInfo* info, int targetType)
1836	{
1837		Entity* weakest=NULL, *myowner;
1838		F32 dHP;
1839		F32 weakestdHP=0;
1840		F32 rangeSQR = range*range;
1841		F32 distSQR;
1842	
1843		//	myowner only allows owner as target. This section tries to buff teammates
1844		//	the following section, targets the owner. it is after so that it can replace the teammates
1845		if(ai->teamMemberInfo.team && (targetType != kTargetType_MyOwner) && (targetType != kTargetType_MyCreator)){
1846			AITeamMemberInfo* member;
1847			S32 isTitan = ai->brain.type == AI_BRAIN_MALTA_HERCULES_TITAN;
1848			
1849			for(member = ai->teamMemberInfo.team->members.list; member; member = member->next){
1850				//	valid ents to buff are entities that aren't self and alive.
1851				//	targettype_mypet requires that the ent is a pet
1852				Entity *entMember = member->entity;
1853				int isValidEnt = (entMember != e) && (entMember->pchar->attrCur.fHitPoints > 0);
1854				if (targetType == kTargetType_MyPet)
1855				{
1856					isValidEnt &= (entMember->erOwner == erGetRef(e));
1857				}
1858				else if (targetType == kTargetType_MyCreation)
1859				{
1860					isValidEnt &= (entMember->erCreator == erGetRef(e));
1861				}
1862				if(isValidEnt){
1863					AttribMod *pmod;
1864					AttribModListIter iter;
1865					bool bActive=false;
1866					const BasePower *ppowBase = info ? info->power->ppowBase : NULL;
1867					
1868					if(isTitan){
1869						AIVars* aiMember = ENTAI(entMember);
1870						
1871						if(aiMember->brain.type != AI_BRAIN_MALTA_HERCULES_TITAN){
1872							continue;
1873						}
1874					}
1875	
1876					if(info)
1877					{
1878						if(!aiPowerTargetAllowed(e, info, entMember, true))
1879							continue;
1880					}
1881	
1882	
1883					if(info && !(info->groupFlags & AI_POWERGROUP_HEAL_ALLY))
1884					{
1885						EntityRef myRef = erGetRef(e);
1886						pmod = modlist_GetFirstMod(&iter, &entMember->pchar->listMod);
1887						while(pmod!=NULL){
1888							if(pmod->ptemplate->ppowBase==ppowBase && pmod->erSource == myRef){
1889								bActive=true;
1890								break;
1891							}
1892							pmod = modlist_GetNextMod(&iter);
1893						}
1894					}
1895	
1896					if(bActive)
1897						continue;
1898					
1899					distSQR = distance3Squared(ENTPOS(e), ENTPOS(entMember));
1900					if (distSQR <= rangeSQR) {
1901						dHP = entMember->pchar->attrMax.fHitPoints - entMember->pchar->attrCur.fHitPoints;
1902						// Prefer weak members, otherwise prefer those in melee, 1/X chance of just skipping a guy, so that not everyone heals/buffs the same guy
1903						if (!weakest || rand()%3 && (dHP > weakestdHP || (dHP == weakestdHP && ABS_TIME_SINCE(ENTAI(member->entity)->time.wasAttacked) < SEC_TO_ABS(5)))) {
1904							weakest = entMember;
1905							weakestdHP = dHP;
1906						}
1907					}
1908				}
1909			}
1910		}
1911		if ((targetType != kTargetType_MyPet) && (targetType != kTargetType_MyCreation))
1912		{
1913			EntityRef owner = targetType == kTargetType_MyCreator ? e->erCreator : e->erOwner;
1914			if(owner && (myowner = erGetEnt(owner)))
1915			{
1916				AttribMod *pmod;
1917				AttribModListIter iter;
1918				bool bActive=false;
1919				const BasePower *ppowBase = info ? info->power->ppowBase : NULL;
1920	
1921				if(info && !(info->groupFlags & AI_POWERGROUP_HEAL_ALLY))
1922				{
1923					pmod = modlist_GetFirstMod(&iter, &myowner->pchar->listMod);
1924					while(pmod!=NULL){
1925						if(pmod->ptemplate->ppowBase==ppowBase){
1926							bActive=true;
1927							break;
1928						}
1929						pmod = modlist_GetNextMod(&iter);
1930					}
1931				}
1932	
1933				distSQR = distance3Squared(ENTPOS(e), ENTPOS(myowner));
1934				if (!bActive && distSQR <= rangeSQR) {
1935					dHP = myowner->pchar->attrMax.fHitPoints - myowner->pchar->attrCur.fHitPoints;
1936					// Prefer weak members, otherwise prefer those in melee, 1/X chance of just skipping a guy, so that not everyone heals/buffs the same guy
1937					if (!weakest || rand()%3 && (dHP > weakestdHP || (dHP == weakestdHP && ABS_TIME_SINCE(ENTAI(myowner)->time.wasAttacked) < SEC_TO_ABS(5)))) {
1938						weakest = myowner;
1939						weakestdHP = dHP;
1940					}
1941				}
1942			}
1943		}
1944		return weakest;
1945	}

 

This function consists of 2 main subroutines - one starts at #1845 and ends at #1910 and another starts at #1911 and ends at #1943. First of them searches all targets those need the buff except for the Owner, and another one looks at the Owner. Problem is - the value "weakest" will likely be non-zero at the moment it gets to the second subroutine, and as it's coded now it won't be overwritten thus it results that Owner gets support from the pets from the LAST order, when it should be receiving buff in the FIRST order, otherwise the robots are a junk that worth only recycling. Thea'z "positronic matrix" salvage in game, so robots shud obey laws of robotics, first of which is NOT TO LET THEIR CREATOR BE HURT (2nd is obey the Creator), and only 3rd of which is NOT TO LET THEMSELVES BE HURT. Yet robots those're in game put the 3rd law above the 1st, which's total blastheadness in its crystallic solid form. Interesting to note that according to how it's coded if your character has LOW HP, the robot may prefer shield the character over other pets, you can test it on live, do major injury to yourself, then summon protector bots, they may shield you first at that case.

 

In order to fix it Devs need to swap these subroutine places. In my experimenting on private server it did the trick.

 

psbots.thumb.jpg.d13979f6e9f9b9407d623523380f2897.jpg

 

Also it's possible to make even stronger assumption, for instance if do this:

1937                    if (!weakest || rand()%3 && (dHP > weakestdHP || (dHP == weakestdHP && ABS_TIME_SINCE(ENTAI(myowner)->time.wasAttacked) < SEC_TO_ABS(5)))) {
replace to

1937                    if (!weakest || (dHP > weakestdHP) || (dHP == weakestdHP) ) {
(it's what l have on private server) then the need of buffing the Owner will be stronger, and the other members will be buffed only when they have Higher HP delta (maxHP-currentHP) than the owner (or special effect is unable to be cast onto owner, bots for instance have NOT lost ability to cast shield on other robot after this replacement FYI). If completely skip the string:

1937                    if ( true ) {
Then the Owner will be buffed/healed even when he (or Nice Beautiful She, or Our Imperial Majesty) has 70% of maximum HP, when there might be teammates with 10 HP and they won't receive the buff/heal that would otherwise save their lives. So it's double edged sword... But what is clear is that it IS a bug that bots cast FF on Owner in the last order, and it IS to be fixed, and it IS to be fixed this instant. It's the Merry Christmas, so letz be nice & fix it now!!! 😊

 

Edited by Purrfekshawn

To keep this game safe, We have to give it to the world.

Arc ID #13097 - Archvillain Beatdown, try it out!

Arc ID #21066 - Archvillain Beatdown - Past Edition!

Letz now talk about existing Incarnate Lore Pets:

https://forums.homecomingservers.com/topic/50351-incarnate-lore-pets-look-through-fix-and-improve/

Link to comment
Share on other sites

  • Game Master

This is directed at the Original Post, but something for all users to know.  Server programming is past the scope of this whole forum.

 

Key distinction, that: Not just bug reports, the entire forum itself.  We are interested in hearing bug reporting from a player perspective. And the majority of readers in these forums are not programmers.  Including yours truly, I'm nobody special.  I put myself in that grouping as well.

 

Put simply and respectfully, there is no frame of reference for players to discuss this past your own perspective.

 

All I can tell you-- if there is a call for a programmer, specialist, or other technical work to be made, there will be an APB made in the Developers Corner area.

 

Edited by GM Tahquitz

Homecoming: City of Heroes -- Want to play? Start here. - Enjoy helping others? Join us as a GM.

 

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...