From: <la...@us...> - 2011-07-27 23:14:15
|
Revision: 7563 http://planeshift.svn.sourceforge.net/planeshift/?rev=7563&view=rev Author: landson Date: 2011-07-27 23:14:08 +0000 (Wed, 27 Jul 2011) Log Message: ----------- implemented Decay Modified Paths: -------------- soc/2011/combat/src/client/modehandler.cpp soc/2011/combat/src/client/modehandler.h soc/2011/combat/src/common/net/messages.cpp soc/2011/combat/src/common/net/messages.h soc/2011/combat/src/server/bulkobjects/psattackmelee.cpp soc/2011/combat/src/server/bulkobjects/psattackmelee.h soc/2011/combat/src/server/bulkobjects/psattackrange.cpp soc/2011/combat/src/server/bulkobjects/psattackrange.h soc/2011/combat/src/server/combatmanager.cpp Modified: soc/2011/combat/src/client/modehandler.cpp =================================================================== --- soc/2011/combat/src/client/modehandler.cpp 2011-07-27 22:15:22 UTC (rev 7562) +++ soc/2011/combat/src/client/modehandler.cpp 2011-07-27 23:14:08 UTC (rev 7563) @@ -156,6 +156,7 @@ msghandler->Unsubscribe(this,MSGTYPE_WEATHER); msghandler->Unsubscribe(this,MSGTYPE_NEWSECTOR); msghandler->Unsubscribe(this,MSGTYPE_COMBATEVENT); + msghandler->Unsubscribe(this,MSGTYPE_SPECCOMBATEVENT); msghandler->Unsubscribe(this,MSGTYPE_CACHEFILE); } if (randomgen) @@ -170,6 +171,7 @@ msghandler->Subscribe(this,MSGTYPE_MODE); msghandler->Subscribe(this,MSGTYPE_WEATHER); msghandler->Subscribe(this,MSGTYPE_NEWSECTOR); + msghandler->Subscribe(this,MSGTYPE_SPECCOMBATEVENT); msghandler->Subscribe(this,MSGTYPE_COMBATEVENT); msghandler->Subscribe(this,MSGTYPE_CACHEFILE); @@ -329,6 +331,9 @@ case MSGTYPE_COMBATEVENT: HandleCombatEvent(me); return; + case MSGTYPE_SPECCOMBATEVENT: + HandleSpecialCombatEvent(me); + return; case MSGTYPE_CACHEFILE: HandleCachedFile(me); @@ -1637,7 +1642,32 @@ return object; } +void ModeHandler::HandleSpecialCombatEvent(MsgEntry* me) +{ + psSpecialCombatEventMessage event(me); + if(!psengine->IsGameLoaded()) + return; // Drop if we haven't loaded + + // Get the relevant entities + GEMClientActor* atObject = (GEMClientActor*)celclient->FindObject(event.attacker_id); + GEMClientActor* tarObject = (GEMClientActor*)celclient->FindObject(event.target_id); + + if (!atObject || !tarObject ) + { + Bug1("NULL Attacker or Target combat event sent to client!"); + return; + } + + SetCombatAnim( atObject, event.attack_anim ); + + SetCombatAnim( tarObject, event.defense_anim ); + + + + + +} void ModeHandler::HandleCombatEvent(MsgEntry* me) { psCombatEventMessage event(me); @@ -1695,6 +1725,7 @@ } } + csString ModeHandler::MungeName(GEMClientActor* obj, bool startOfPhrase) { csString nameTarget = obj->GetName(); Modified: soc/2011/combat/src/client/modehandler.h =================================================================== --- soc/2011/combat/src/client/modehandler.h 2011-07-27 22:15:22 UTC (rev 7562) +++ soc/2011/combat/src/client/modehandler.h 2011-07-27 23:14:08 UTC (rev 7563) @@ -189,6 +189,7 @@ void HandleWeatherMessage(MsgEntry* me); void HandleNewSectorMessage(MsgEntry* me); void HandleCombatEvent(MsgEntry* me); + void HandleSpecialCombatEvent(MsgEntry* me); void HandleCachedFile(MsgEntry* me); bool ProcessLighting(LightingSetting *color, float pct); Modified: soc/2011/combat/src/common/net/messages.cpp =================================================================== --- soc/2011/combat/src/common/net/messages.cpp 2011-07-27 22:15:22 UTC (rev 7562) +++ soc/2011/combat/src/common/net/messages.cpp 2011-07-27 23:14:08 UTC (rev 7563) @@ -3789,7 +3789,45 @@ #endif //--------------------------------------------------------------------------- +PSF_IMPLEMENT_MSG_FACTORY(psSpecialCombatEventMessage,MSGTYPE_SPECCOMBATEVENT); +psSpecialCombatEventMessage::psSpecialCombatEventMessage(uint32_t clientnum, EID attacker, EID target, int attack_anim,int defense_anim) +{ + msg.AttachNew(new MsgEntry(sizeof(uint8_t) + 4 * sizeof(uint32_t) + sizeof(int8_t) )); + msg->SetType(MSGTYPE_SPECCOMBATEVENT); + msg->clientnum = clientnum; + + msg->Add( (uint32_t) attack_anim ); + msg->Add( (uint32_t) defense_anim ); + msg->Add(attacker.Unbox()); + msg->Add(target.Unbox()); + valid=!(msg->overrun); +} +void psSpecialCombatEventMessage::SetClientNum(int cnum) +{ + msg->clientnum = cnum; +} + +psSpecialCombatEventMessage::psSpecialCombatEventMessage(MsgEntry *message) +{ + attack_anim = message->GetUInt32(); + defense_anim = message->GetUInt32(); + attacker_id = EID(message->GetUInt32()); + target_id = EID(message->GetUInt32()); + + // Sets valid flag based on message overrun state + valid=!(message->overrun); +} +csString psSpecialCombatEventMessage::ToString(NetBase::AccessPointers * /*accessPointers*/) +{ + csString msgtext; + + msgtext.AppendFmt("Attack Anim: %d Defense Anim: %d Attacker: %d Target: %d", + attack_anim, defense_anim, attacker_id.Unbox(), target_id.Unbox()); + + return msgtext; +} + PSF_IMPLEMENT_MSG_FACTORY(psCombatEventMessage,MSGTYPE_COMBATEVENT); psCombatEventMessage::psCombatEventMessage(uint32_t clientnum, Modified: soc/2011/combat/src/common/net/messages.h =================================================================== --- soc/2011/combat/src/common/net/messages.h 2011-07-27 22:15:22 UTC (rev 7562) +++ soc/2011/combat/src/common/net/messages.h 2011-07-27 23:14:08 UTC (rev 7563) @@ -144,6 +144,7 @@ MSGTYPE_AUTHCHARACTERAPPROVED, MSGTYPE_CHAR_CREATE_CP, MSGTYPE_COMBATEVENT, + MSGTYPE_SPECCOMBATEVENT, MSGTYPE_LOOT, MSGTYPE_LOOTITEM, MSGTYPE_LOOTREMOVE, @@ -2577,6 +2578,40 @@ #endif /** + * Messages from the server to the client, similar to combat events below, but for special attacks + * + */ +class psSpecialCombatEventMessage : public psMessageCracker +{ +public: + EID attacker_id; + EID target_id; + int attack_anim; + int defense_anim; + + /** Create psMessageBytes struct for outbound use */ + psSpecialCombatEventMessage(uint32_t clientnum, + EID attacker, + EID target, + int attack_anim, + int defense_anim); + + void SetClientNum(int cnum); + + /** Crack incoming psMessageBytes struct for inbound use */ + psSpecialCombatEventMessage(MsgEntry *message); + + PSF_DECLARE_MSG_FACTORY(); + + /** + * @brief Converts the message into human readable string. + * + * @param accessPointers A struct to a number of access pointers. + * @return Return a human readable string for the message. + */ + virtual csString ToString(NetBase::AccessPointers* accessPointers); +}; +/** * Messages sent from server to client containing each detailed * combat event. */ Modified: soc/2011/combat/src/server/bulkobjects/psattackmelee.cpp =================================================================== --- soc/2011/combat/src/server/bulkobjects/psattackmelee.cpp 2011-07-27 22:15:22 UTC (rev 7562) +++ soc/2011/combat/src/server/bulkobjects/psattackmelee.cpp 2011-07-27 23:14:08 UTC (rev 7563) @@ -57,7 +57,11 @@ psAttackMelee::psAttackMelee() { - + calc_decay = psserver->GetMathScriptEngine()->FindScript("Calculate Decay"); + if ( !calc_decay ) + { + Error1("Calculate Decay Script could not be found. Check the math_scripts DB table."); + } } psAttackMelee::~psAttackMelee() { @@ -178,14 +182,15 @@ //checks the chances of the attack being successful, will implement a script, if it is successful then the attack goes through, if its not then it dont if(!CalculateSuccess(event)) { - psserver->SendSystemInfo(attacker->GetClientID(),"Your Attack failed");//will flesh this out a bit later + psserver->SendSystemInfo(attacker->GetClientID(),"Your Attack was blocked");//will flesh this out a bit later + Decay(attacker->GetCharacterData(),target->GetCharacterData(),event,false); return; } int affectedCount = 0; if (radius < 0.01f) // single target { - AffectTarget(attacker, target, target, power); + AffectTarget(attacker, target, target, power,event); affectedCount++; } else // AOE (Area of Effect) @@ -238,12 +243,19 @@ continue; } - AffectTarget(attacker, target, nearby[i], power); + AffectTarget(attacker, target, nearby[i], power,event); affectedCount++; } if (affectedCount > 0) { + gemActor *gemAttacker = dynamic_cast<gemActor*> ((gemObject *) attacker); + gemActor *gemTarget = dynamic_cast<gemActor*> ((gemObject *) target); + if(Animation) + psSpecialCombatEventMessage evt(attacker->GetClientID(), attacker->GetEID(), target->GetEID(), gemAttacker->FindAnimIndex(Animation),gemTarget->FindAnimIndex("hit")); + else + psSpecialCombatEventMessage evt(attacker->GetClientID(), attacker->GetEID(), target->GetEID(), event->weapon->GetAttackAnimID(attacker->GetCharacterData()),gemTarget->FindAnimIndex("hit")); + psserver->SendSystemInfo(attacker->GetClientID(), "%s affected %d %s.", name.GetData(), affectedCount, (affectedCount == 1) ? "target" : "targets"); } else @@ -255,7 +267,61 @@ } +void psAttackMelee::Decay(psCharacter* attacker_data, psCharacter* target_data,psCombatAttackGameEvent *event, bool hit, bool affectattacker) +{ + MathVar *weaponDecay = NULL; + MathVar *blockDecay = NULL; + MathVar *armorDecay = NULL; + MathEnvironment env; + psItem *weapon = attacker_data->Inventory().GetEffectiveWeaponInSlot(event->GetWeaponSlot()); + psItem *blockingWeapon = target_data->Inventory().GetEffectiveWeaponInSlot(event->GetWeaponSlot(),true); + psItem *struckArmor = target_data->Inventory().GetEffectiveArmorInSlot(event->AttackLocation); + + // we are guaranteed some armor is present - real one, race one or base one + CS_ASSERT(struckArmor); + float ArmorVsWeapon = weapon->GetArmorVSWeaponResistance(struckArmor->GetBaseStats()); + + // clamp value between 0 and 1 + ArmorVsWeapon = ArmorVsWeapon > 1.0F ? 1.0F : ArmorVsWeapon < 0.0F ? 0.0F : ArmorVsWeapon; + + env.Define("Weapon", weapon); // weapon that was used to attack + env.Define("BlockingWeapon", blockingWeapon); // weapon that blocked the attack + env.Define("Armor", struckArmor); // armor hit + env.Define("ArmorVsWeapon", ArmorVsWeapon); // armor vs weapon effectiveness + env.Define("Blocked", !hit); // identifies whether this attack was blocked + + calc_decay->Evaluate(&env); + + weaponDecay = env.Lookup("WeaponDecay"); + blockDecay = env.Lookup("BlockingDecay"); + armorDecay = env.Lookup("ArmorDecay"); + + if(hit) + { + if (weapon) + { + if(affectattacker) + weapon->AddDecay(weaponDecay->GetValue()); + } + if (struckArmor) + { + struckArmor->AddDecay(armorDecay->GetValue()); + } + } + else + { + if (weapon) + { + if(affectattacker) + weapon->AddDecay(weaponDecay->GetValue()); + } + if (blockingWeapon) + { + blockingWeapon->AddDecay(blockDecay->GetValue()); + } + } +} bool psAttackMelee::CalculateSuccess(psCombatAttackGameEvent *event) { @@ -276,7 +342,7 @@ return false; } -bool psAttackMelee::AffectTarget(gemObject* attacker, gemObject* origTarget, gemObject* target, float power) +bool psAttackMelee::AffectTarget(gemObject* attacker, gemObject* origTarget, gemObject* target, float power, psCombatAttackGameEvent *event) { if (!attacker->GetClient()->IsAllowedToAttack(target,false)) return false; @@ -298,5 +364,9 @@ env.Define("Power", power); outcome->Run(&env); - + if(origTarget == target) + Decay(attacker->GetCharacterData(), target->GetCharacterData(),event,true,true); + else + Decay(attacker->GetCharacterData(), target->GetCharacterData(),event,true,false); + return true; } \ No newline at end of file Modified: soc/2011/combat/src/server/bulkobjects/psattackmelee.h =================================================================== --- soc/2011/combat/src/server/bulkobjects/psattackmelee.h 2011-07-27 22:15:22 UTC (rev 7562) +++ soc/2011/combat/src/server/bulkobjects/psattackmelee.h 2011-07-27 23:14:08 UTC (rev 7563) @@ -75,8 +75,9 @@ */ bool CalculateSuccess(psCombatAttackGameEvent *event); private: - bool AffectTarget(gemObject* attacker, gemObject* origTarget, gemObject* target, float power); - + bool AffectTarget(gemObject* attacker, gemObject* origTarget, gemObject* target, float power, psCombatAttackGameEvent *event); + void Decay(psCharacter* attacker_data, psCharacter* target_data,psCombatAttackGameEvent *event, bool hit,bool affectplayer = true); + MathScript* calc_decay; float PowerLevel(psCharacter *attacker, psItem* weapon) const; float AttackSpeed; csString Animation; ///< possible attack animation Modified: soc/2011/combat/src/server/bulkobjects/psattackrange.cpp =================================================================== --- soc/2011/combat/src/server/bulkobjects/psattackrange.cpp 2011-07-27 22:15:22 UTC (rev 7562) +++ soc/2011/combat/src/server/bulkobjects/psattackrange.cpp 2011-07-27 23:14:08 UTC (rev 7563) @@ -57,6 +57,12 @@ psAttackRange::psAttackRange() { + + calc_decay = psserver->GetMathScriptEngine()->FindScript("Calculate Decay"); + if ( !calc_decay ) + { + Error1("Calculate Decay Script could not be found. Check the math_scripts DB table."); + } } psAttackRange::~psAttackRange() @@ -112,6 +118,61 @@ } } +void psAttackRange::Decay(psCharacter* attacker_data, psCharacter* target_data,psCombatAttackGameEvent *event, bool hit, bool affectattacker) +{ + MathVar *weaponDecay = NULL; + MathVar *blockDecay = NULL; + MathVar *armorDecay = NULL; + MathEnvironment env; + + psItem *weapon = attacker_data->Inventory().GetEffectiveWeaponInSlot(event->GetWeaponSlot()); + psItem *blockingWeapon = target_data->Inventory().GetEffectiveWeaponInSlot(event->GetWeaponSlot(),true); + psItem *struckArmor = target_data->Inventory().GetEffectiveArmorInSlot(event->AttackLocation); + + // we are guaranteed some armor is present - real one, race one or base one + CS_ASSERT(struckArmor); + float ArmorVsWeapon = weapon->GetArmorVSWeaponResistance(struckArmor->GetBaseStats()); + + // clamp value between 0 and 1 + ArmorVsWeapon = ArmorVsWeapon > 1.0F ? 1.0F : ArmorVsWeapon < 0.0F ? 0.0F : ArmorVsWeapon; + + env.Define("Weapon", weapon); // weapon that was used to attack + env.Define("BlockingWeapon", blockingWeapon); // weapon that blocked the attack + env.Define("Armor", struckArmor); // armor hit + env.Define("ArmorVsWeapon", ArmorVsWeapon); // armor vs weapon effectiveness + env.Define("Blocked", !hit); // identifies whether this attack was blocked + + calc_decay->Evaluate(&env); + + weaponDecay = env.Lookup("WeaponDecay"); + blockDecay = env.Lookup("BlockingDecay"); + armorDecay = env.Lookup("ArmorDecay"); + + if(hit) + { + if (weapon) + { + if(affectattacker) + weapon->AddDecay(weaponDecay->GetValue()); + } + if (struckArmor) + { + struckArmor->AddDecay(armorDecay->GetValue()); + } + } + else + { + if (weapon) + { + if(affectattacker) + weapon->AddDecay(weaponDecay->GetValue()); + } + if (blockingWeapon) + { + blockingWeapon->AddDecay(blockDecay->GetValue()); + } + } +} bool psAttackRange::IsDualWield(psCharacter* attacker) { if(type->OneHand) @@ -159,7 +220,8 @@ //checks the chances of the attack being successful, will implement a script, if it is successful then the attack goes through, if its not then it dont if(!CalculateSuccess(event, range)) { - psserver->SendSystemInfo(attacker->GetClientID(),"Your Attack failed");//will flesh this out a bit later + psserver->SendSystemInfo(attacker->GetClientID(),"Your Attack was blocked");//may make some more of thsi later + Decay(event->GetAttackerData(),event->GetTargetData(),event,false); return; } bool hasAmmo = true; @@ -212,7 +274,7 @@ int affectedCount = 0; if (radius < 0.01f) // single target { - AffectTarget(attacker, target, target, power); + AffectTarget(attacker, target, target, power,event); affectedCount++; } else // AOE (Area of Effect) @@ -265,7 +327,7 @@ continue; } - AffectTarget(attacker, target, nearby[i], power); + AffectTarget(attacker, target, nearby[i], power,event); affectedCount++; } @@ -322,7 +384,7 @@ return power->GetValue(); } -bool psAttackRange::AffectTarget(gemObject* attacker, gemObject* origTarget, gemObject* target, float power) +bool psAttackRange::AffectTarget(gemObject* attacker, gemObject* origTarget, gemObject* target, float power, psCombatAttackGameEvent *event) { if (!attacker->GetClient()->IsAllowedToAttack(target,false)) return false; @@ -344,4 +406,9 @@ env.Define("Power", power); outcome->Run(&env); + if(origTarget == target) + Decay(attacker->GetCharacterData(), target->GetCharacterData(),event,true,true); + else + Decay(attacker->GetCharacterData(), target->GetCharacterData(),event,true,false); + return true; } \ No newline at end of file Modified: soc/2011/combat/src/server/bulkobjects/psattackrange.h =================================================================== --- soc/2011/combat/src/server/bulkobjects/psattackrange.h 2011-07-27 22:15:22 UTC (rev 7562) +++ soc/2011/combat/src/server/bulkobjects/psattackrange.h 2011-07-27 23:14:08 UTC (rev 7563) @@ -73,8 +73,10 @@ bool CalculateSuccess(psCombatAttackGameEvent *event, float range); private: - bool AffectTarget(gemObject* attacker, gemObject* origTarget, gemObject* target, float power); + bool AffectTarget(gemObject* attacker, gemObject* origTarget, gemObject* target, float power, psCombatAttackGameEvent *event); + void Decay(psCharacter* attacker_data, psCharacter* target_data,psCombatAttackGameEvent *event, bool hit, bool affectplayer = true); + MathScript* calc_decay; float PowerLevel(psCharacter *attacker, psItem* weapon, float range) const; float AttackSpeed; csString Animation; ///< possible attack animation Modified: soc/2011/combat/src/server/combatmanager.cpp =================================================================== --- soc/2011/combat/src/server/combatmanager.cpp 2011-07-27 22:15:22 UTC (rev 7562) +++ soc/2011/combat/src/server/combatmanager.cpp 2011-07-27 23:14:08 UTC (rev 7563) @@ -371,7 +371,7 @@ psAttackBookMessage mesg(client->GetClientNum()); csArray<psAttack*> attacks = psserver->GetCacheManager()->GetAllAttacks(); - for(int i = 0; i < attacks.GetSize(); i++) + for(size_t i = 0; i < attacks.GetSize(); i++) { if(attacks[i]->CanAttack(client)) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |