PDA

View Full Version : custom NPC melee


zeiksz2
01-05-2008, 01:02 PM
i never liked 500+ hitting mobs, but not even fluffy darkpaw who could smash my face without having a weapon for 20+ what i barely could manage with a tarnished two handed sword.. well.. first time in my eq life i can take revenge on these fippies :)

the following code part goes into attack.cpp, our target is the npc::attack



if((max_dmg+eleBane) != 0 && damage > (max_dmg+eleBane)) {
mlog(COMBAT__DAMAGE, "Damage (%d) is above max (%d). Setting to max.", damage, (max_dmg+eleBane));
damage = (max_dmg+eleBane);
}

******* above is just for finding the place.. start is here *******
//this goes only for pets
if (this->GetOwnerID())
{
//this applies only for h2h, so that is not so low dam
if (skillinuse==HAND_TO_HAND)
{
damage=mylevel/20;
}
//formula is after player formula
//no "weapon skill" is counted, instead we say level * 10, saying "max weapon skill" with that
damage=MakeRandomInt(1,(weapon_damage * ((GetSTR()*20) + (GetSkill(OFFENSE)*15) + (mylevel*10)) / 1000)+eleBane);
}
******* code ends here *****

//THIS IS WHERE WE CHECK TO SEE IF WE HIT:
if(other->IsClient() && other->CastToClient()->IsSitting()) {
mlog(COMBAT__DAMAGE, "Client %s is sitting. Hitting for max damage (%d).", other->GetName(), (max_dmg+eleBane));
damage = (max_dmg+eleBane);
} else {



so.. all we do is putting the melee formula of client into npc.. this above goes only for pets by default (so you will have to put weapon in their hands). if you want to apply it for all the NPCs then remove the first "if". if you want to leave them on poor hand-to-hand melee then comment the second "if" out as well. this second makes sure to improve the "damage" if mob is fighting with hand to hand.. so previously quad150ing guards will not start quad1punching you just because you gave them no rusty weapon

todo: check if the creature is humanoid.. creatures biting actually do not need weapon - wont do it at 2am..

zeiksz2
01-06-2008, 04:04 AM
quickfix: sitting

if other is sitting then we are to hit max damage. we did not count max damage, what is actually the top of the makerandomint.. so the damage calculation splits up into two lines



max_dmg=(weapon_damage * ((GetSTR()*20) + (GetSkill(OFFENSE)*15) + (mylevel*10)) / 1000);
damage=MakeRandomInt(1,max_dmg+eleBane);




and so we set up the variable max_dmg for the sitting damage (what is not makerandomint, but damage=max_dmg+elebane).

zeiksz2
01-06-2008, 05:48 AM
todone: improving h2h a bit

hand to hand realizes always weapon_damage 1, so unless we have such weapon (did not saw any) we can talk with bare handed fight (what can mean biting, clawing, etc). this was very low damage with previous codes even on higher levels



min_dmg=1;
if (weapon_damage==1) {
//possible hand to hand was done,
//we don't want that unarmed, brawling, clawing, biting stuff behaving like a w00sh, so we correct weapon damage to level
weapon_damage=(mylevel/5);
}
max_dmg=(weapon_damage * ((GetSTR()*20) + (GetSkill(OFFENSE)*15) + (mylevel*10)) / 1000);
damage=MakeRandomInt(min_dmg+eleBane,max_dmg+eleBa ne);



this code will allow to do "kinda okay" punch melee.. hands as weapon will be = with a (NPCLevel divided 5) damage weapon..

next step: size matters

zeiksz2
01-06-2008, 06:25 AM
if we are taller or are higher in level then we may say we are stronger.. if higher in level then we are experienced, if taller then we are phisically stronger.. this should be counted to attack damage.

see the other side of thing: dragonfoo... er.. gnome warriors will be less.. umm... lucky

this here goes to client::attack


//damage formula needs some work
int min_hit = 1;
****** custom code from here ******
int sizematters = (mylevel-otherlevel)+(this->GetSize()-other->GetSize()); //yes, let it be negative too, if we are tiny we have less "luck"
if (sizematters>0) {min_hit+=sizematters;} //if we are tough our minimum is higher, but if we are "weaker" our minimum can't go bellow 1
int max_hit=
(weapon_damage * ((GetSTR()*20) + (GetSkill(OFFENSE)*15) + (GetSkill(skillinuse)*2) / 1000)
+ sizematters
);
***** custom code ends here *****



and this goes to NPC::attack



min_dmg=1;
if (weapon_damage==1) {
//possible hand to hand was done,
//we don't want that unarmed, brawling, clawing, biting stuff behaving like a w00sh, so we correct weapon damage to level
weapon_damage=(mylevel/5);
}
int sizematters = (mylevel-otherlevel)+(this->GetSize()-other->GetSize()); //yes, let it be negative too, if we are tiny we have less "luck"
if (sizematters>0) {min_dmg+=sizematters;} //if we are tough our minimum is higher, but if we are "weaker" our minimum can't go bellow 1
max_dmg=
(weapon_damage * ((GetSTR()*20) + (GetSkill(OFFENSE)*15) + (mylevel*10)) / 1000)
+ sizematters
);
if (max_dmg<=min_dmg+eleBane) { damage=min_dmg+eleBane; }
else { damage=MakeRandomInt(min_dmg+eleBane,max_dmg+eleBa ne); }



note: also "corrected" that Client::attack wont count with level * 10, but skill in use * 2.. so with that if you are low skilled with sword but still use it, you will hit less as well..

zeiksz2
01-06-2008, 06:41 AM
duhh.. cant edit again..



The administrator has specified that you can only edit messages for 5 minutes after you have posted. This limit has expired, so you must contact the administrator to make alterations on your message.



so syntax problem in both attax



(weapon_damage * ((GetSTR()*20) + (GetSkill(OFFENSE)*15) + (GetSkill(skillinuse)*2)) / 1000)
+ sizematters
;



is correct.. like by NPC it is with level (check the ")"...)

zeiksz2
01-06-2008, 09:22 AM
another problem i found in my npc::attack code is that max_dmg is not normal int type, so if it would get negative it gets 65535-. so used a temp int



min_dmg=1;
if (weapon_damage==1) {
//possible hand to hand was done,
//we don't want that unarmed, brawling, clawing, biting stuff behaving like a w00sh, so we correct weapon damage to level
weapon_damage=(mylevel/5);
}
int sizematters = ((int)mylevel-(int)otherlevel)+((int)this->GetSize()-(int)other->GetSize()); //yes, let it be negative too, if we are tiny we have less "luck"
if (sizematters>0) {min_dmg+=sizematters;} //if we are tough our minimum is higher, but if we are "weaker" our minimum can't go bellow 1
int temp_max_dmg =
(weapon_damage * ((GetSTR()*20) + (GetSkill(OFFENSE)*15) + (mylevel*10)) / 1000)
+ sizematters
;
if (temp_max_dmg>=1) { max_dmg = temp_max_dmg; } else { max_dmg = 1; }
if (max_dmg<=min_dmg+eleBane) { damage=min_dmg+eleBane; }
else { damage=MakeRandomInt(min_dmg+eleBane,max_dmg+eleBa ne); }



edit: next to be done: no slamming (bash without shield) for several mobs - i mean a giant slamming you into ground is ok, but a qeynos guard is more then a duhhh..

zeiksz2
01-12-2008, 12:04 PM
an "ok" calculation

for player (client::attack)


int max_hit=
weapon_damage+
weapon_damage*(GetSkill(OFFENSE)/100)*(GetSkill(skillinuse)/100)
+ sizematters
+ GetSTR()/10 + GetDEX()/25 + GetINT()/100 + GetWIS()/75
;




for pets, mobs, etc (npc::attack)


int temp_max_dmg =
weapon_damage+
weapon_damage*(mylevel*5/100)*(mylevel*5/100)
//player's GetSkill(OFFENSE) being a master gives 1.0
//player's GetSkill(skillinuse)
+ sizematters
+ GetSTR()/10 + GetDEX()/25 + GetINT()/100 + GetWIS()/75
;




if you rip off the first "weapon_damage+" line you may get to better ballanced (less kickass) melee, but that would make casters happy who would get barely hit on lower levels..

after what i do count: well weapon damage as prior. then i add to this the weapon damage compared to master level in offense and actual weapon skill (by npc this is level *5 so they are same level with each weapon) then we add the sizematters modifier as a "bane" damage (see prev posts about size and level differences) then we give +1 damage after each 10str, 25dex, 100int, 75wis.. why int and wis? well.. ever wondered why war gets "some" of such gears (pre-hardcoresonycrap of course).. because knowing your enemy is power.. not much.. but +1 dam may be worth for any regular minded (human for example and not troll) warrior worth to make that 100 int or 75 wis...

zeiksz2
01-20-2008, 03:51 AM
Mob::TryBackstab has restriction for player (mr. IsClient()) to backstabb only with piercing weapon.. this i want to apply for mob (npc/pet) too, but got some problem with code (not a pretty one tho')



//make sure we have a proper weapon if we are a client.
//if(IsClient()) {

if (IsClient()) {
const ItemInst* weapon = NULL;
weapon = CastToClient()->GetInv().GetItem(SLOT_PRIMARY);
if(!weapon || (weapon->GetItem()->ItemType != ItemTypePierce)) {
Message_StringID(13, BACKSTAB_WEAPON);
return;
}
} else if (IsNPC()) {
const Item_Struct* weapon = NULL;
int32 eid = CastToNPC()->GetEquipment(SLOT_PRIMARY);
if (eid != 0) weapon = database.GetItem(eid);
if (!weapon || (weapon->ItemType!=ItemTypePierce && weapon->ItemType!=ItemType2HPierce))
{
return;
}
}
//}



so NPC part i was just copy/pasting together and seems not to work.. the cast2npc-getequipbyslot gives always zero value, so the stuff will make exit on every mob backstabb attempt

any idea?

ChaosSlayer
01-21-2008, 11:34 AM
a question for you
if no NPC can hit hard wihout a weapon - what gona happen to all the npc who do not normaly carry weapons? Like animals, insects, various non humanoid monsters?

zeiksz2
01-22-2008, 06:30 PM
min_dmg=1;
if (weapon_damage==1) {
//possible hand to hand was done,
//we don't want that unarmed, brawling, clawing, biting stuff behaving like a w00sh, so we correct weapon damage to level
weapon_damage=(mylevel/5);
}
....


i tested that too too, and i disliked that as well.. so i set this stuff so their weapon's damage is counted after their level.. so 1-4 levels have fist weapon of 1 damage, 2-9 has 2, etc.. (weapon damage at that position of code returned always 1 if no weapon present from a previous function call).

of course if you put rusty dagger to a L20 mobs hand that will downgrade his damage at moment. rusty dagger 3 dam, L20 unarmed 5 dam