void SabBeh_AttackVsAttack( gentity_t *self, sabmech_t *mechSelf, gentity_t *otherOwner, sabmech_t *mechOther, qboolean *selfMishap, qboolean *otherMishap ) {//set the saber behavior for two attacking blades hitting each other qboolean atkfake = (self->client->ps.userInt3 & (1 << FLAG_ATTACKFAKE)) ? qtrue : qfalse; qboolean otherfake = (otherOwner->client->ps.userInt3 & (1 << FLAG_ATTACKFAKE)) ? qtrue : qfalse; if(atkfake && !otherfake) {//self is sololy faking //set self SabBeh_AddBalance(self, mechSelf, 1, qtrue); #ifdef _DEBUG mechSelf->behaveMode = SABBEHAVE_BLOCKFAKED; #endif //set otherOwner if (WP_SabersCheckLock(self, otherOwner)) { self->client->ps.userInt3 |= ( 1 << FLAG_LOCKWINNER ); self->client->ps.saberBlocked = BLOCKED_NONE; otherOwner->client->ps.saberBlocked = BLOCKED_NONE; } SabBeh_AddBalance(otherOwner, mechOther, -1, qtrue); #ifdef _DEBUG mechOther->behaveMode = SABBEHAVE_ATTACK; #endif } else if(otherfake && !atkfake) {//only otherOwner is faking //set self if (WP_SabersCheckLock(otherOwner, self)) { self->client->ps.saberBlocked = BLOCKED_NONE; otherOwner->client->ps.userInt3 |= ( 1 << FLAG_LOCKWINNER ); otherOwner->client->ps.saberBlocked = BLOCKED_NONE; } SabBeh_AddBalance(self, mechSelf, -1, qtrue); #ifdef _DEBUG mechSelf->behaveMode = SABBEHAVE_ATTACK; #endif //set otherOwner SabBeh_AddBalance(otherOwner, mechOther, 1, qtrue); #ifdef _DEBUG mechOther->behaveMode = SABBEHAVE_BLOCKFAKED; #endif } else {//either both are faking or neither is faking. Either way, it's cancelled out //set self SabBeh_AddBalance(self, mechSelf, 1, qtrue); #ifdef _DEBUG mechSelf->behaveMode = SABBEHAVE_ATTACK; #endif //set otherOwner SabBeh_AddBalance(otherOwner, mechOther, 1, qtrue); #ifdef _DEBUG mechOther->behaveMode = SABBEHAVE_ATTACK; #endif } }
void SabBeh_AttackVsBlock( gentity_t *attacker, sabmech_t *mechAttacker, gentity_t *blocker, sabmech_t *mechBlocker, vec3_t hitLoc, qboolean hitSaberBlade, qboolean *attackerMishap, qboolean *blockerMishap) {//set the saber behavior for an attacking vs blocking/parrying blade impact qboolean startSaberLock = qfalse; qboolean parried = G_BlockIsParry(blocker, attacker, hitLoc); qboolean atkparry = G_InAttackParry(blocker); qboolean atkfake = (attacker->client->ps.userInt3 & (1 << FLAG_ATTACKFAKE)) ? qtrue : qfalse; G_BlockIsQuickParry(blocker,attacker,hitLoc);//Return value was never used, so I just call it now if(parried && blocker->r.svFlags & SVF_BOT && BOT_ATTACKPARRYRATE * botstates[blocker->s.number]->settings.skill > Q_irand(0,999)) {//bot performed an attack parry (by cheating a bit) //G_Printf("%i: %i: Bot Cheat Attack Parried\n", level.time, blocker->s.number); atkparry = qtrue; } /* if(parried && atkparry) { G_Printf("%i: %i: Attack Parried\n", level.time, blocker->s.number); } */ if(BG_SuperBreakWinAnim(attacker->client->ps.torsoAnim)) {//attacker was attempting a superbreak and he hit someone who could block the move, rail him for screwing up. *attackerMishap = SabBeh_RollBalance(attacker, mechAttacker, qtrue,qfalse); SabBeh_AddBalance(attacker, mechAttacker, 2, qtrue); #ifdef _DEBUG mechAttacker->behaveMode = SABBEHAVE_ATTACKPARRIED; #endif SabBeh_AddBalance(blocker, mechBlocker, -1, qfalse); #ifdef _DEBUG mechBlocker->behaveMode = SABBEHAVE_BLOCK; #endif } else if(atkfake) {//attacker faked before making this attack, treat like standard attack/attack if(parried) {//defender parried the attack fake. *attackerMishap = SabBeh_RollBalance(attacker, mechAttacker, atkparry,qtrue); SabBeh_AddBalance(attacker, mechAttacker, MPCOST_PARRIED_ATTACKFAKE, qtrue); #ifdef _DEBUG mechAttacker->behaveMode = SABBEHAVE_ATTACK; #endif if (blocker->client->pers.cmd.buttons & BUTTON_15 && blocker->client->ps.fd.forcePowerLevel[FP_SABER_DEFENSE] >= FORCE_LEVEL_2) { attacker->client->ps.userInt3 |= (1 << FLAG_QUICKPARRY); } else { attacker->client->ps.userInt3 |= ( 1 << FLAG_PARRIED ); } SabBeh_AddBalance(blocker, mechBlocker, MPCOST_PARRYING_ATTACKFAKE, qfalse); #ifdef _DEBUG mechBlocker->behaveMode = SABBEHAVE_BLOCK; #endif } else if(atkparry) { saberKnockOutOfHand(&g_entities[attacker->client->ps.saberEntityNum], attacker, vec3_origin); } else {//otherwise, the defender stands a good chance of having his defensives broken. SabBeh_AddBalance(attacker, mechAttacker, -1, qtrue); if(attacker->client->ps.fd.saberAnimLevel == SS_DESANN) SabBeh_AddBalance(blocker, mechBlocker, 2, qfalse); #ifdef _DEBUG mechAttacker->behaveMode = SABBEHAVE_ATTACK; #endif if (WP_SabersCheckLock(attacker, blocker)) { attacker->client->ps.userInt3 |= ( 1 << FLAG_LOCKWINNER ); attacker->client->ps.saberBlocked = BLOCKED_NONE; blocker->client->ps.saberBlocked = BLOCKED_NONE; startSaberLock = qtrue; } #ifdef _DEBUG mechBlocker->behaveMode = SABBEHAVE_BLOCKFAKED; #endif } } else if(hitSaberBlade && BG_InSlowBounce(&blocker->client->ps) && blocker->client->ps.userInt3 & (1 << FLAG_OLDSLOWBOUNCE) && attacker->client->ps.fd.saberAnimLevel == SS_TAVION) {//blocker's saber was directly hit while in a slow bounce, disarm the blocker! mechBlocker->doButterFingers = qtrue; blocker->client->ps.saberAttackChainCount = 0; #ifdef _DEBUG mechBlocker->behaveMode = SABBEHAVE_BLOCKFAKED; #endif //set attacker SabBeh_AddBalance(attacker, mechAttacker, -3, qtrue); #ifdef _DEBUG mechAttacker->behaveMode = SABBEHAVE_ATTACK; #endif } else {//standard attack //set blocker #ifdef _DEBUG mechBlocker->behaveMode = SABBEHAVE_BLOCK; #endif //set attacker if(parried) { //parry values if(attacker->client->ps.saberMove == LS_A_LUNGE || attacker->client->ps.saberMove == LS_SPINATTACK || attacker->client->ps.saberMove == LS_SPINATTACK_DUAL) {//attacker's lunge was parried, force mishap. *attackerMishap = SabBeh_RollBalance(attacker, mechAttacker, qtrue,atkparry); } else { *attackerMishap = SabBeh_RollBalance(attacker, mechAttacker, atkparry,atkparry); } SabBeh_AddBalance(attacker, mechAttacker, MPCOST_PARRIED, qtrue); #ifdef _DEBUG mechAttacker->behaveMode = SABBEHAVE_ATTACKPARRIED; #endif //[QuickParry] if (blocker->client->pers.cmd.buttons & BUTTON_15 && blocker->client->ps.fd.forcePowerLevel[FP_SABER_DEFENSE] >= FORCE_LEVEL_2) { attacker->client->ps.userInt3 |= ( 1 << FLAG_QUICKPARRY); } else { attacker->client->ps.userInt3 |= ( 1 << FLAG_PARRIED ); } //[/QuickParry] SabBeh_AddBalance(blocker, mechBlocker, MPCOST_PARRYING, qfalse); } else {//blocked values SabBeh_AddBalance(attacker, mechAttacker, -1, qtrue); if(attacker->client->ps.fd.saberAnimLevel == SS_TAVION) {//aqua styles deals MP to players that don't parry it. SabBeh_AddBalance(blocker, mechBlocker, 2, qfalse); } else if(attacker->client->ps.fd.saberAnimLevel == SS_STRONG) { blocker->client->ps.fd.forcePower -= 2; } else if(attacker->client->ps.fd.saberAnimLevel==SS_TAVION && attacker->client->skillLevel[SK_GREENSTYLE] == FORCE_LEVEL_3 && (attacker->client->ps.userInt3 & FLAG_QUICKPARRY)) { SabBeh_AddBalance(blocker, mechBlocker, 2, qfalse); } #ifdef _DEBUG mechAttacker->behaveMode = SABBEHAVE_ATTACKBLOCKED; #endif //SabBeh_AddBalance(blocker, 1, qfalse); } } if(!OnSameTeam(attacker, blocker) || g_friendlySaber.integer) {//don't do parries or charge/regen DP unless we're in a situation where we can actually hurt the target. if(parried) {//parries don't cost any DP and they have a special animation //qboolean regenSound = qfalse; mechBlocker->doParry = qtrue; } else if(!startSaberLock) {//normal saber blocks //update the blocker's block move blocker->client->ps.saberLockFrame = 0; //break out of saberlocks. WP_SaberBlockNonRandom(blocker, hitLoc, qfalse); } } //do saber DP cost. /* // debugger message. G_Printf("%i: %i: Saber Block Cost: %i atk: %s %s blk: %s %s\n", level.time, blocker->s.number, OJP_SaberBlockCost(blocker, attacker, hitLoc), GetStringForID( animTable, attacker->client->ps.torsoAnim ), GetStringForID( SaberMoveTable, attacker->client->ps.saberMove ), GetStringForID( animTable, blocker->client->ps.torsoAnim ), GetStringForID( SaberMoveTable, blocker->client->ps.saberMove ) ); */ //[ExpSys] -- [DUALRAWR] G_DodgeDrain(blocker, attacker, OJP_SaberBlockCost(blocker, attacker, hitLoc)); //[/ExpSys] //costs FP as well. BG_AddFatigue(&blocker->client->ps, 1); }
void SabBeh_AttackVsAttack( gentity_t *self, sabmech_t *mechSelf, gentity_t *otherOwner, sabmech_t *mechOther, qboolean *selfMishap, qboolean *otherMishap ) {//set the saber behavior for two attacking blades hitting each other qboolean atkfake = (self->client->ps.userInt3 & (1 << FLAG_ATTACKFAKE)) ? qtrue : qfalse; qboolean otherfake = (otherOwner->client->ps.userInt3 & (1 << FLAG_ATTACKFAKE)) ? qtrue : qfalse; if(atkfake && !otherfake) {//self is sololy faking //set self SabBeh_AddBalance(self, mechSelf, MPCOST_ATTACK_FAKE_ATTACKED, qtrue); #ifdef _DEBUG mechSelf->behaveMode = SABBEHAVE_BLOCKFAKED; #endif //set otherOwner if (WP_SabersCheckLock(self, otherOwner)) { self->client->ps.userInt3 |= ( 1 << FLAG_LOCKWINNER ); self->client->ps.saberBlocked = BLOCKED_NONE; otherOwner->client->ps.saberBlocked = BLOCKED_NONE; } SabBeh_AddBalance(otherOwner, mechOther, MPCOST_ATTACKING_ATTACK_FAKE, qtrue); #ifdef _DEBUG mechOther->behaveMode = SABBEHAVE_ATTACK; #endif } else if(otherfake && !atkfake) {//only otherOwner is faking //set self if (WP_SabersCheckLock(otherOwner, self)) { self->client->ps.saberBlocked = BLOCKED_NONE; otherOwner->client->ps.userInt3 |= ( 1 << FLAG_LOCKWINNER ); otherOwner->client->ps.saberBlocked = BLOCKED_NONE; } SabBeh_AddBalance(self, mechSelf, MPCOST_ATTACKING_ATTACK_FAKE, qtrue); #ifdef _DEBUG mechSelf->behaveMode = SABBEHAVE_ATTACK; #endif //set otherOwner SabBeh_AddBalance(otherOwner, mechOther, MPCOST_ATTACK_FAKE_ATTACKED, qtrue); #ifdef _DEBUG mechOther->behaveMode = SABBEHAVE_BLOCKFAKED; #endif } else {//either both are faking or neither is faking. Either way, it's cancelled out //set self SabBeh_AddBalance(self, mechSelf, MPCOST_ATTACK_ATTACK, qtrue); #ifdef _DEBUG mechSelf->behaveMode = SABBEHAVE_ATTACK; #endif //set otherOwner SabBeh_AddBalance(otherOwner, mechOther, MPCOST_ATTACK_ATTACK, qtrue); #ifdef _DEBUG mechOther->behaveMode = SABBEHAVE_ATTACK; #endif } if(g_debugsaberbehavior.integer) { G_Printf("%i: SaberBeh Attack vs Attack: %i (self %s:%s): %s, %i (other %s:%s): %s\n", level.time, self->s.number, GetStringForID(SaberMoveTable, self->playerState->saberMove), GetStringForID(SaberBlockedTable, self->playerState->saberBlocked), GetStringForID(sabBehaveTable, mechSelf->behaveMode), otherOwner->s.number, GetStringForID(SaberMoveTable, otherOwner->playerState->saberMove), GetStringForID(SaberBlockedTable, otherOwner->playerState->saberBlocked), GetStringForID(sabBehaveTable, mechOther->behaveMode)); } }