|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Development::Bots Forum for bots. |
07-15-2011, 01:14 PM
|
Hill Giant
|
|
Join Date: Apr 2008
Location: Milwaukee
Posts: 141
|
|
Bot armor color + texture
With NPC's you can change texture and armor colors. Is this possible with bots other than having to create specific new items?
|
07-15-2011, 02:23 PM
|
Developer
|
|
Join Date: Jul 2007
Location: my own little world
Posts: 751
|
|
i've never tried. the bots display the item you give them. are you trying to change the default color of the item you give the bot?
|
07-15-2011, 04:19 PM
|
Hill Giant
|
|
Join Date: Sep 2006
Posts: 172
|
|
Couldn't a bot version on this be added to bot.ccp?
Columns would have to be added to the botinventory or bots tables in the database because I would assume any player doing this would want it on a per bot basis.
Code:
int8 Inventory::CalcMaterialFromSlot(sint16 equipslot)
{
switch(equipslot)
{
case SLOT_HEAD:
return MATERIAL_HEAD;
case SLOT_CHEST:
return MATERIAL_CHEST;
case SLOT_ARMS:
return MATERIAL_ARMS;
case SLOT_BRACER01:
case SLOT_BRACER02:
return MATERIAL_BRACER;
case SLOT_HANDS:
return MATERIAL_HANDS;
case SLOT_LEGS:
return MATERIAL_LEGS;
case SLOT_FEET:
return MATERIAL_FEET;
case SLOT_PRIMARY:
return MATERIAL_PRIMARY;
case SLOT_SECONDARY:
return MATERIAL_SECONDARY;
default:
return 0xFF;
}
}
Criimson
|
07-15-2011, 04:22 PM
|
Developer
|
|
Join Date: Jul 2007
Location: my own little world
Posts: 751
|
|
BotAddEquipItem() and BotRemoveEquipItem() call that method.
|
07-15-2011, 06:49 PM
|
Hill Giant
|
|
Join Date: Sep 2006
Posts: 172
|
|
Quote:
Originally Posted by Congdar
BotAddEquipItem() and BotRemoveEquipItem() call that method.
|
Yea, but it could be rewritten to call an almost identical function created within bots.cpp that added lines to also check for armor slot color. Or I guess it might be easier to add a call within the bot spawn that reads color per slot.
Criimson
|
07-16-2011, 05:14 PM
|
Hill Giant
|
|
Join Date: Apr 2008
Location: Milwaukee
Posts: 141
|
|
Somewhere in there too is a color sceme for naked bots too. I skimmed though a few ccp files but couldn't come up with anything. My C++ is aweful at best. Best i could find was some armor wear stuff.
|
07-16-2011, 05:28 PM
|
Hill Giant
|
|
Join Date: Sep 2006
Posts: 172
|
|
You know I am interested in this as well. I'll look into it soon. Right now I am focused on finishing up some bot ai, but when I am finished I will look at what can be done. Would be nice to have my rogue in all black
|
07-16-2011, 06:57 PM
|
Banned
|
|
Join Date: Oct 2009
Posts: 312
|
|
Criimson on a roll! Would be excellent if you can spare the time when you're not busy.
|
07-16-2011, 08:03 PM
|
Hill Giant
|
|
Join Date: Sep 2006
Posts: 172
|
|
I looked at the DB to see how I could work this in with minimal structure changes. And am running some test code right now.
I am currently looking at a command:
#bot armorcolor <slot> <color>
This will write to the botinventory and alter the color column. Simple enough. Will most likely require a redying when the armor item changes, but bots require no regeants so shouldnt be an issue.
My question is: Does anyone know how to translate the color ##s?
For instance "4280012197" is used quite a bit. It is a 10 digit number. So it isn't R ### B ### G ### which is what I was hoping. Any ideas?
I can always summon some prismatic dyes and note changes as I mess with a piece of armor and derive what is happening but figured someone would know.
Criimson
EDIT: I am posting some code changes to the "Server Code Submissions" section later tonight and will add this if I finish it.
|
07-16-2011, 08:14 PM
|
Demi-God
|
|
Join Date: Aug 2010
Posts: 1,742
|
|
Perhaps it is hex? 0xFF1BCDA5
|
07-16-2011, 08:19 PM
|
Hill Giant
|
|
Join Date: Sep 2006
Posts: 172
|
|
Good idea.
I'll google a hex converter for colors and test that
Hmm seems hex colors use 6 digits since hex also uses a-f.
Did find this site though
Digital Colors
I see that some are listed as ### ### ### maybe the last or first digit is a black/white level
|
07-16-2011, 08:28 PM
|
Demi-God
|
|
Join Date: Aug 2010
Posts: 1,742
|
|
Georges NPC editor seems to let you edit tint settings for NPCs. It may help to figure out how the colors map. There's also a link for a color picker app that would probably be handy, but the link seems to be broken. :(
http://www.georgestools.eqemulator.net/
|
07-16-2011, 09:22 PM
|
Hill Giant
|
|
Join Date: Sep 2006
Posts: 172
|
|
Well I have the code in place and ready to go once I figure out the color column. So far it doesnt really look like it does anything. I tested the code and change the color of my chanters robe to 1234567890. It wrote perfectly to the DB. I logged her out and back in just in case, but no visible change to the robe. Wife time, but I'll look into it more tonight.
Criimson
|
07-17-2011, 02:33 PM
|
Hill Giant
|
|
Join Date: Sep 2006
Posts: 172
|
|
Just a heads up
Lost some sleep and my wife is teasing me , but I am close to having it working. Here is an image of what I have right now.
Uploaded with ImageShack.us
BTW that is Highelf Cleric newbie armor so should be all green.
Criimson
|
|
|
|
07-18-2011, 05:14 PM
|
Hill Giant
|
|
Join Date: Sep 2006
Posts: 172
|
|
Hello everyone
The code is 99% finished. Apparently uint64 isn't allowed or at least I am not getting it to work. Therefore, even though the color range is ### ### ### # the number defaults to 2billion-ish for every number higher than that. I am currently looking for alternatives. In the meantime though here is the .patch to play around with what I have. There is also an sql as I added a rule_values option for a server allowing primary secondary slots to be dyed (havent tested these yet). I also tweaked mez ai a bit (will continue to until the chanter is where I want it) and also added checks for shrink and setfollowdistance to make sure the bot belongs to the client.
Code:
Index: bot.cpp
===================================================================
--- bot.cpp (revision 1976)
+++ bot.cpp (working copy)
@@ -3567,12 +3567,15 @@
const Item_Struct* item = 0;
const ItemInst* inst = 0;
+ uint32 spawnedbotid = 0;
+ spawnedbotid = this->GetBotIDForTint();
+
inst = GetBotItem(SLOT_HANDS);
if(inst) {
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MATERIAL_HANDS] = item->Material;
- ns->spawn.colors[MATERIAL_HANDS].color = GetEquipmentColor(MATERIAL_HANDS);
+ ns->spawn.colors[MATERIAL_HANDS].color = Bot::GetEquipmentColor(MATERIAL_HANDS);
}
}
@@ -3581,7 +3584,7 @@
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MATERIAL_HEAD] = item->Material;
- ns->spawn.colors[MATERIAL_HEAD].color = GetEquipmentColor(MATERIAL_HEAD);
+ ns->spawn.colors[MATERIAL_HEAD].color = Bot::GetEquipmentColor(MATERIAL_HEAD);
}
}
@@ -3590,7 +3593,7 @@
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MATERIAL_ARMS] = item->Material;
- ns->spawn.colors[MATERIAL_ARMS].color = GetEquipmentColor(MATERIAL_ARMS);
+ ns->spawn.colors[MATERIAL_ARMS].color = Bot::GetEquipmentColor(MATERIAL_ARMS);
}
}
@@ -3599,7 +3602,7 @@
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MATERIAL_BRACER] = item->Material;
- ns->spawn.colors[MATERIAL_BRACER].color = GetEquipmentColor(MATERIAL_BRACER);
+ ns->spawn.colors[MATERIAL_BRACER].color = Bot::GetEquipmentColor(MATERIAL_BRACER);
}
}
@@ -3608,7 +3611,7 @@
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MATERIAL_BRACER] = item->Material;
- ns->spawn.colors[MATERIAL_BRACER].color = GetEquipmentColor(MATERIAL_BRACER);
+ ns->spawn.colors[MATERIAL_BRACER].color = Bot::GetEquipmentColor(MATERIAL_BRACER);
}
}
@@ -3617,7 +3620,7 @@
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MATERIAL_CHEST] = item->Material;
- ns->spawn.colors[MATERIAL_CHEST].color = GetEquipmentColor(MATERIAL_CHEST);
+ ns->spawn.colors[MATERIAL_CHEST].color = Bot::GetEquipmentColor(MATERIAL_CHEST);
}
}
@@ -3626,7 +3629,7 @@
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MATERIAL_LEGS] = item->Material;
- ns->spawn.colors[MATERIAL_LEGS].color = GetEquipmentColor(MATERIAL_LEGS);
+ ns->spawn.colors[MATERIAL_LEGS].color = Bot::GetEquipmentColor(MATERIAL_LEGS);
}
}
@@ -3635,7 +3638,7 @@
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MATERIAL_FEET] = item->Material;
- ns->spawn.colors[MATERIAL_FEET].color = GetEquipmentColor(MATERIAL_FEET);
+ ns->spawn.colors[MATERIAL_FEET].color = Bot::GetEquipmentColor(MATERIAL_FEET);
}
}
@@ -3645,6 +3648,7 @@
if(item) {
if(strlen(item->IDFile) > 2)
ns->spawn.equipment[MATERIAL_PRIMARY] = atoi(&item->IDFile[2]);
+ ns->spawn.colors[MATERIAL_PRIMARY].color = Bot::GetEquipmentColor(MATERIAL_PRIMARY);
}
}
@@ -3654,6 +3658,7 @@
if(item) {
if(strlen(item->IDFile) > 2)
ns->spawn.equipment[MATERIAL_SECONDARY] = atoi(&item->IDFile[2]);
+ ns->spawn.colors[MATERIAL_SECONDARY].color = Bot::GetEquipmentColor(MATERIAL_SECONDARY);
}
}
}
@@ -10061,7 +10066,7 @@
c->Message(0, "#bot levitate - Bot levitation (must have proper class in group)");
c->Message(0, "#bot resist - Bot resist buffs (must have proper class in group)");
c->Message(0, "#bot runeme - Enchanter Bot cast Rune spell on you");
- c->Message(0, "#bot shrink - Shaman Bot will shrink you");
+ c->Message(0, "#bot shrink - Shaman or Beastlord will shrink target");
c->Message(0, "#bot endureb - Bot enduring breath (must have proper class in group)");
c->Message(0, "#bot charm - (must have proper class in group)");
c->Message(0, "#bot dire charm - (must have proper class in group)");
@@ -10077,6 +10082,7 @@
c->Message(0, "#bot mana [<bot name or target> | all] - Displays a mana report for all your spawned bots.");
c->Message(0, "#bot setfollowdistance ### - sets target bots follow distance to ### (ie 30 or 250).");
c->Message(0, "#bot [hair|haircolor|beard|beardcolor|face|eyes|heritage|tattoo|details <value>] - Change your BOTs appearance.");
+ c->Message(0, "#bot armorcolor <slot> <value> - #bot help armorcolor for info");
// TODO:
// c->Message(0, "#bot illusion <bot/client name or target> - Enchanter Bot cast an illusion buff spell on you or your target.");
c->Message(0, "#bot pull [<bot name>] [target] - Bot Pulling Target NPC's");
@@ -10121,8 +10127,8 @@
// added Bot follow distance - SetFollowDistance
if(!strcasecmp(sep->arg[1], "setfollowdistance")) {
- if((c->GetTarget() == NULL) || (c->GetTarget() == c) || (!c->GetTarget()->IsBot()) ) {
- c->Message(15, "You must target a bot!");
+ if((c->GetTarget() == NULL) || (c->GetTarget() == c) || (!c->GetTarget()->IsBot()) || (c->GetTarget()->CastToBot()->GetBotOwner() != c)) {
+ c->Message(15, "You must target a bot you own!");
}
else {
int32 BotFollowDistance = atoi(sep->arg[2]);
@@ -10133,7 +10139,83 @@
return;
}
-
+ //bot armor colors
+ if(!strcasecmp(sep->arg[1], "armorcolor")) {
+ if(c->GetTarget() && c->GetTarget()->IsBot() && (c->GetTarget()->CastToBot()->GetBotOwner() == c)) {
+ uint32 botid = c->GetTarget()->CastToBot()->GetBotID();
+ c->Message(0, "BotID = %u", botid);
+ std::string errorMessage;
+ char* Query = 0;
+ uint32 setcolor = atoi(sep->arg[3]);
+ int setslot = atoi(sep->arg[2]);
+ c->Message(0, "setcolor = %i", setcolor);
+ c->Message(0, "setslot = %i", setslot);
+
+ if(sep->arg[2][0] == '\0' || sep->arg[3][0] == '\0') {
+ c->Message(0, "Usage: #bot armorcolor [slot] [color ##] - use #bot help armorcolor for info");
+ return;
+ }
+ else if (sep->arg[3][0] >= 9999999999){
+ c->Message(0, "Invalid color selection - color range 0 - 9999999999");
+ c->Message(0, "Usage: #bot armorcolor [slot] [color ##] - use #bot help armorcolor for info");
+ return;
+ }
+ else{
+ if(database.RunQuery(Query, MakeAnyLenString(&Query, "UPDATE botinventory SET color = %i WHERE slotID = %i AND botID = %u",setcolor, setslot, botid))){
+ int slotmaterial = Inventory::CalcMaterialFromSlot(setslot);
+ c->GetTarget()->CastToBot()->SendWearChange(slotmaterial);
+ }
+ }
+
+ }
+ else {
+ c->Message(15, "You must target a bot you own to do this.");
+ }
+
+ return;
+ }
+ // Help for coloring bot armor
+ if(!strcasecmp(sep->arg[1], "help") && !strcasecmp(sep->arg[2], "armorcolor") ){
+ //read from db
+ char* Query = 0;
+ MYSQL_RES* DatasetResult;
+ MYSQL_ROW DataRow;
+ int dyedprimary = 0;
+ int dyedsecondary = 0;
+
+
+ if(database.RunQuery(Query, MakeAnyLenString(&Query, "SELECT rule_value FROM rule_values WHERE rule_name = 'Bots:DyedPrimary'"), 0, &DatasetResult)) {
+ if(mysql_num_rows(DatasetResult) == 1) {
+ DataRow = mysql_fetch_row(DatasetResult);
+ if(DataRow)
+ dyedprimary = atoi(DataRow[0]);
+ }
+ mysql_free_result(DatasetResult);
+ safe_delete_array(Query);
+ }
+ if(database.RunQuery(Query, MakeAnyLenString(&Query, "SELECT rule_value FROM rule_values WHERE rule_name = 'Bots:DyedSecondary'"), 0, &DatasetResult)) {
+ if(mysql_num_rows(DatasetResult) == 1) {
+ DataRow = mysql_fetch_row(DatasetResult);
+ if(DataRow)
+ dyedsecondary = atoi(DataRow[0]);
+ }
+ mysql_free_result(DatasetResult);
+ safe_delete_array(Query);
+ }
+
+ c->Message(0, "-----------------#bot armorcolor help-----------------------------");
+ c->Message(0, "Armor: 17(Chest/Robe), 7(Arms), 9(Bracer), 12(Hands), 18(Legs), 19(Boots), 2(Helm)");
+ c->Message(0, "------------------------------------------------------------------");
+ if (dyedprimary == 1){c->Message(0, "13 (Primary Weapon Slot - Server Allowed");}
+ if (dyedsecondary == 1){c->Message(0, "14 (Secondary Weapon Slot or Shield - Server Allowed");}
+ c->Message(0, "------------------------------------------------------------------");
+ c->Message(0, "Color: ########## (usage: enter a number from 1 - 10 digits");
+ c->Message(0, "------------------------------------------------------------------");
+ c->Message(0, "Example: #bot armorcolor 17 1644825 would dye the chest black");
+ c->Message(0, "Example: #bot armorcolor 9 4646464646 would dye the wrists purple");
+ return;
+ }
+
if(!strcasecmp(sep->arg[1], "augmentitem")) {
AugmentItem_Struct* in_augment = new AugmentItem_Struct[sizeof(AugmentItem_Struct)];
in_augment->container_slot = 1000;
@@ -11770,8 +11852,8 @@
Group *g = c->GetGroup();
Mob *target = c->GetTarget();
- if(target == NULL || (!target->IsClient() && !target->IsBot()))
- c->Message(15, "You must select a player or bot");
+ if(target == NULL || (!target->IsClient() && !target->IsBot()) || (c->GetTarget()->CastToBot()->GetBotOwner() != c))
+ c->Message(15, "You must select a player or bot you own");
else if(g) {
for(int i=0; i<MAX_GROUP_MEMBERS; i++){
@@ -11797,8 +11879,6 @@
if (c->GetLevel() >= 15) {
Shrinker->Say("Casting Shrink...");
- //Shrinker->CastToBot()->BotRaidSpell(345);
- //Shrinker->CastSpell(345, id), 1);
Shrinker->CastToBot()->SpellOnTarget(345, target);
}
else if (c->GetLevel() <= 14) {
@@ -11810,8 +11890,6 @@
if (c->GetLevel() >= 23) {
Shrinker->Say("Casting Shrink...");
- //Shrinker->CastToBot()->BotRaidSpell(345);
- //Shrinker->CastSpell(345, id), 1);
Shrinker->CastToBot()->SpellOnTarget(345, target);
}
else if (c->GetLevel() <= 22) {
@@ -13742,4 +13820,45 @@
return needHealed;
}
+uint32 Bot::GetEquipmentColor(int8 material_slot) const
+{
+ //Bot tints
+ int32 slotid = 0;
+ uint32 returncolor = 0;
+ uint32 botid = this->GetBotIDForTint();
+
+ //Translate code slot # to DB slot #
+ slotid = Inventory::CalcSlotFromMaterial(material_slot);
+
+ //read from db
+ char* Query = 0;
+ MYSQL_RES* DatasetResult;
+ MYSQL_ROW DataRow;
+
+ if(database.RunQuery(Query, MakeAnyLenString(&Query, "SELECT color FROM botinventory WHERE BotID = %u AND SlotID = %u", botid, slotid), 0, &DatasetResult)) {
+ if(mysql_num_rows(DatasetResult) == 1) {
+ DataRow = mysql_fetch_row(DatasetResult);
+ if(DataRow)
+ returncolor = atoi(DataRow[0]);
+ }
+ mysql_free_result(DatasetResult);
+ safe_delete_array(Query);
+ }
+ return returncolor;
+}
+void Bot::SendWearChange(int8 material_slot)
+{
+ EQApplicationPacket* outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct));
+ WearChange_Struct* wc = (WearChange_Struct*)outapp->pBuffer;
+
+ wc->spawn_id = GetID();
+ wc->material = GetEquipmentMaterial(material_slot);
+ wc->elite_material = IsEliteMaterialItem(material_slot);
+ wc->color.color = GetEquipmentColor(material_slot);
+ wc->wear_slot_id = material_slot;
+
+ entity_list.QueueClients(this, outapp);
+ safe_delete(outapp);
+}
+
#endif
Index: bot.h
===================================================================
--- bot.h (revision 1976)
+++ bot.h (working copy)
@@ -217,6 +217,8 @@
void BotTradeAddItem(uint32 id, const ItemInst* inst, sint16 charges, uint32 equipableSlots, int16 lootSlot, std::string* errorMessage, bool addToDb = true);
void EquipBot(std::string* errorMessage);
bool CheckLoreConflict(const Item_Struct* item);
+ uint32 Bot::GetEquipmentColor(int8 material_slot) const;
+ void Bot::SendWearChange(int8 material_slot);
// Static Class Methods
static void SaveBotGroup(Group* botGroup, std::string botGroupName, std::string* errorMessage);
@@ -297,6 +299,7 @@
// "GET" Class Methods
uint32 GetBotID() { return _botID; }
+ uint32 GetBotIDForTint() const { return _botID; }
uint32 GetBotOwnerCharacterID() { return _botOwnerCharacterID; }
uint32 GetBotSpellID() { return npc_spells_id; }
Mob* GetBotOwner() { return this->_botOwner; }
Index: botspellsai.cpp
===================================================================
--- botspellsai.cpp (revision 1976)
+++ botspellsai.cpp (working copy)
@@ -558,8 +558,15 @@
GroupHasShaman = true;
}
else if (botClass == ENCHANTER){
- botSpell = GetBestBotSpellForMagicBasedSlow(this);
- GroupHasEnchanter = true;
+ //Checking no adds before slow/debuff
+ Mob* addMob = GetFirstIncomingMobToMez(this, botSpell);
+
+ if(addMob){
+ break;}
+ else {
+ botSpell = GetBestBotSpellForMagicBasedSlow(this);
+ GroupHasEnchanter = true;
+ }
}
else if (botClass == BEASTLORD && GroupHasEnchanter == false && GroupHasShaman == false){
botSpell = GetBestBotSpellForDiseaseBasedSlow(this);
@@ -584,6 +591,13 @@
checked_los = true;
}
+ //if enchanter checking if no adds
+ if (botClass == ENCHANTER){
+ Mob* addMob = GetFirstIncomingMobToMez(this, botSpell);
+
+ if(addMob){
+ break;}
+ }
botSpell = GetDebuffBotSpell(this, tar);
SQL
Code:
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Bots:DyedSecondary', '0', 'Allow dying of Secondary Slot (ie shields) 0 - off 1- on');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Bots:DyedPrimary', '0', 'Allow dying of Primary Slot (ie weapons) 0 - off 1- on');
Criimson
EDIT: I have gotten purply orange green blue black white so might leave as is - would appreciate feedback on what might be needed or done
As seen here:
Uploaded with ImageShack.us
|
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -4. The time now is 05:15 PM.
|
|
|
|
|
|
|
|
|
|
|
|
|