TFS 1.0? You'll have to compile it yourself though.
game.cpp, find void Game::updateCreatureType(Creature* creature) method and replace it with:
C++:
void Game::updateCreatureType(Creature* creature)
{
const Player* masterPlayer = nullptr;
uint32_t creatureId = creature->getID();
CreatureType_t creatureType = creature->getType();
if (creatureType == CREATURETYPE_MONSTER) {
const Creature* master = creature->getMaster();
if (master) {
masterPlayer = master->getPlayer();
if (masterPlayer) {
creatureType = CREATURETYPE_SUMMON_OTHERS;
}
}
}
//send to clients
SpectatorHashSet spectators;
map.getSpectators(spectators, creature->getPosition(), true, true);
if (creatureType == CREATURETYPE_SUMMON_OTHERS) {
for (Creature* spectator : spectators) {
Player* player = spectator->getPlayer();
if (masterPlayer == player) {
player->sendCreatureType(creatureId, CREATURETYPE_SUMMON_OWN);
}
}
} else {
for (Creature* spectator : spectators) {
spectator->getPlayer()->sendCreatureType(creatureId, creatureType);
}
}
}
And ProtocolGame::AddCreature(NetworkMessage& msg, const Creature* creature, bool known, uint32_t remove) in protocolgame.cpp, replace it with this:
C++:
void ProtocolGame::AddCreature(NetworkMessage& msg, const Creature* creature, bool known, uint32_t remove)
{
CreatureType_t creatureType = creature->getType();
const Player* otherPlayer = creature->getPlayer();
if (known) {
msg.add<uint16_t>(0x62);
msg.add<uint32_t>(creature->getID());
} else {
msg.add<uint16_t>(0x61);
msg.add<uint32_t>(remove);
msg.add<uint32_t>(creature->getID());
msg.addByte(creatureType);
msg.addString(creature->getName());
}
if (creature->isHealthHidden()) {
msg.addByte(0x00);
} else {
msg.addByte(std::ceil((static_cast<double>(creature->getHealth()) / std::max<int32_t>(creature->getMaxHealth(), 1)) * 100));
}
msg.addByte(creature->getDirection());
if (!creature->isInGhostMode() && !creature->isInvisible()) {
AddOutfit(msg, creature->getCurrentOutfit());
} else {
static Outfit_t outfit;
AddOutfit(msg, outfit);
}
LightInfo lightInfo;
creature->getCreatureLight(lightInfo);
msg.addByte(player->isAccessPlayer() ? 0xFF : lightInfo.level);
msg.addByte(lightInfo.color);
msg.add<uint16_t>(creature->getStepSpeed() / 2);
msg.addByte(player->getSkullClient(creature));
msg.addByte(player->getPartyShield(otherPlayer));
if (!known) {
msg.addByte(player->getGuildEmblem(otherPlayer));
}
if (creatureType == CREATURETYPE_MONSTER) {
const Creature* master = creature->getMaster();
if (master) {
const Player* masterPlayer = master->getPlayer();
if (masterPlayer) {
if (masterPlayer == player) {
creatureType = CREATURETYPE_SUMMON_OWN;
}
}
}
}
msg.addByte(creatureType); // Type (for summons)
msg.addByte(creature->getSpeechBubble());
msg.addByte(0xFF); // MARK_UNMARKED
if (otherPlayer) {
msg.add<uint16_t>(otherPlayer->getHelpers());
} else {
msg.add<uint16_t>(0x00);
}
msg.addByte(player->canWalkthroughEx(creature) ? 0x00 : 0x01);
}
It should work by not informing users that this is a summon (so the red shield should not appear). I don't know what other implications this may have, feel free to test it

If you want to remove the green shield as well then use this version of functions (removes both green and red):
C++:
void Game::updateCreatureType(Creature* creature)
{
const Player* masterPlayer = nullptr;
uint32_t creatureId = creature->getID();
CreatureType_t creatureType = creature->getType();
//send to clients
SpectatorHashSet spectators;
map.getSpectators(spectators, creature->getPosition(), true, true);
for (Creature* spectator : spectators) {
spectator->getPlayer()->sendCreatureType(creatureId, creatureType);
}
}
C++:
void ProtocolGame::AddCreature(NetworkMessage& msg, const Creature* creature, bool known, uint32_t remove)
{
CreatureType_t creatureType = creature->getType();
const Player* otherPlayer = creature->getPlayer();
if (known) {
msg.add<uint16_t>(0x62);
msg.add<uint32_t>(creature->getID());
} else {
msg.add<uint16_t>(0x61);
msg.add<uint32_t>(remove);
msg.add<uint32_t>(creature->getID());
msg.addByte(creatureType);
msg.addString(creature->getName());
}
if (creature->isHealthHidden()) {
msg.addByte(0x00);
} else {
msg.addByte(std::ceil((static_cast<double>(creature->getHealth()) / std::max<int32_t>(creature->getMaxHealth(), 1)) * 100));
}
msg.addByte(creature->getDirection());
if (!creature->isInGhostMode() && !creature->isInvisible()) {
AddOutfit(msg, creature->getCurrentOutfit());
} else {
static Outfit_t outfit;
AddOutfit(msg, outfit);
}
LightInfo lightInfo;
creature->getCreatureLight(lightInfo);
msg.addByte(player->isAccessPlayer() ? 0xFF : lightInfo.level);
msg.addByte(lightInfo.color);
msg.add<uint16_t>(creature->getStepSpeed() / 2);
msg.addByte(player->getSkullClient(creature));
msg.addByte(player->getPartyShield(otherPlayer));
if (!known) {
msg.addByte(player->getGuildEmblem(otherPlayer));
}
msg.addByte(creatureType); // Type (for summons)
msg.addByte(creature->getSpeechBubble());
msg.addByte(0xFF); // MARK_UNMARKED
if (otherPlayer) {
msg.add<uint16_t>(otherPlayer->getHelpers());
} else {
msg.add<uint16_t>(0x00);
}
msg.addByte(player->canWalkthroughEx(creature) ? 0x00 : 0x01);
}
Again, this has not been tested, but it should do what you're asking for. I'm not aware of any side-effects this may have, so check carefully.