Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

[Release] Real working Combo Attack including Advanced Combo and correct animations

Status
Not open for further replies.
Junior Spellweaver
Joined
Apr 14, 2008
Messages
100
Reaction score
0
This is for a real working combo attack meaning the orbs charge up and get used up by the finishing moves.
Also includes Advanced Combo's effects if player has that skill.
All the code is here, if you can't implement it you don't deserve to have a working combo.

File #1: Player.h

Declare this under private:
PHP:
	int combo; // Combo Attack

Add these to class Player
PHP:
	void setCombo(int combo){ // Combo Attack
		this->combo = combo;
	}
	int getCombo(){ // Combo Attack
		return combo;
	}

File #2: Skills.h

Add these to class Skills
PHP:
	static void end1111002(Player* player); // Combo Attack
	static void addCombo(Player* player, int hits); // Combo Attack
	static void clearCombo(Player* player); // Combo Attack

File #3: SkillsPacket.h

Add this to class SkillsPacket
PHP:
	static void showCombo(Player* player, vector <Player*> players, int time); // Combo Attack

File #4: SkillsPacket.cpp

Add these to the bottom
PHP:
void SkillsPacket::showCombo(Player *player, vector <Player*> players, int time){ // show combos to everyone on map
	Packet packet = Packet();
	packet.addHeader(0x3a);
	packet.addByte(0);
	packet.addByte(0);
	packet.addByte((char)0x20);
	packet.addByte(0);
	packet.addByte(0);
	packet.addByte(0);
	packet.addByte(0);
	packet.addByte(0);
	packet.addShort(player->getCombo()+1);
	packet.addInt(1111002);
	packet.addInt(time);
	packet.addShort(0);
	packet.addByte(0);
	packet.packetSend(player);
	packet= Packet();
	packet.addHeader(0x86);
	packet.addInt(player->getPlayerid());
	packet.addByte(0);
	packet.addByte(0);
	packet.addByte((char)0x20);
	packet.addByte(0);
	packet.addByte(0);
	packet.addByte(0);
	packet.addByte(0);
	packet.addByte(0);
	packet.addShort(player->getCombo()+1);
	packet.addByte(0);
	packet.sendTo(player, players, 0);
}

File #5: Timer.h

Declare this:
PHP:
int timeLeft (int id); // check skill time

File #6: Timer.cpp

Add this:
PHP:
int Timer::timeLeft (int id){ // check skill time
    return getTimer(id)->t - GetTickCount();
}

File #7: Skills.cpp

Add these to class SkillTimer (it's near the top)
PHP:
    int skillTime (Player* player, char* name){
        int timeleft = 0;
        for(unsigned int i=0; i<timers.size(); i++){
            if(player == timers[i].player && strcmp(timers[i].name, name) == 0)    {
                timeleft = Timer::timer->timeLeft(timers[i].id);
            }
        }
        return timeleft;
    }

Add these it's easy to figure out where
PHP:
		else if(strcmp(name, "end1111002") == 0) Skills::end1111002(player); // Combo Attack

Add these it's easy to figure out where
PHP:
	else if(skillid == 1111002){ // Combo Attack
		timer->stop(player, "end1111002");
		end1111002(player);
	}

Add these it's easy to figoure out where
PHP:
	else if(skillid == 1111002){ // Combo Attack
		player->setCombo(0);
		vals.push_back(player->getCombo()+1);
		timer->stop(player, "end1111002");
		SkillsPacket::useSkill(player, Maps::info[player->getMap()].Players , skillid, skills[skillid][level].time*1000, 0, 0, (char)0x20, 0, 0, 0, 0, 0, vals, 1);
		timer->setSkillTimer(player, "end1111002", skills[skillid][level].time*1000);
	}

Add these to the bottom
PHP:
void Skills::end1111002(Player* player){ // Combo Attack
	player->setCombo(0);
	SkillsPacket::endSkill(player, Maps::info[player->getMap()].Players, 0, 0, (char)0x20, 0, 0, 0, 0, 0, 1);
}

void Skills::addCombo(Player* player, int hits){ // add combo orbs
    if(timer->skillTime(player, "end1111002")>0){
        if(player->getCombo()<0) player->setCombo(0);
        int maxcombo = 0;
        if(player->skills->getSkillLevel(1120003)>0) maxcombo = skills[1120003][player->skills->getSkillLevel(1120003)].x;
        else maxcombo = skills[1111002][player->skills->getSkillLevel(1111002)].x;
        if(player->getCombo()>=maxcombo){
                player->setCombo(maxcombo);
        }
        else{
            for(int i=0; i<hits; i++){
                player->setCombo(player->getCombo()+1);
                if(player->skills->getSkillLevel(1120003)>0 && rand()%100<30+player->skills->getSkillLevel(1120003))
                    player->setCombo(player->getCombo()+1); // 4th job skill gives chance to add second orb
            }
            if(player->getCombo()>=maxcombo) player->setCombo(maxcombo);
            SkillsPacket::showCombo(player, Maps::info[player->getMap()].Players, timer->skillTime(player, "end1111002"));
        }
    }
}

void Skills::clearCombo(Player* player){ // finishing moves panic coma
    player->setCombo(0);
    SkillsPacket::showCombo(player, Maps::info[player->getMap()].Players, timer->skillTime(player, "end1111002"));
}

File #8: Mobs.cpp

Replace your Mobs::damageMob function, becareful here, it's damageMob NOT damageMobSkill or damageMobS

PHP:
void Mobs::damageMob(Player* player, unsigned char* packet){
	MobsPacket::damageMob(player, Maps::info[player->getMap()].Players, packet);
	int howmany = packet[1]/0x10;
	int hits = packet[1]%0x10;
	int map = player->getMap();
	int skillid = getInt(packet+2);
	int totaldmg = 0;
	if(skillid > 0)
		Skills::useAttackSkill(player, skillid);
	for(int i=0; i<howmany; i++){
		int mobid = getInt(packet+14+i*(22+4*(hits-1)));
		for(int k=0; k<hits; k++){
			int damage = getInt(packet+32+i*(22+4*(hits-1))+k*4);
			totaldmg = totaldmg + damage;
			for(unsigned int j=0; j<mobs[map].size(); j++){
				if(mobs[map][j]->getID() == mobid){
					mobs[map][j]->setHP(mobs[map][j]->getHP()-damage);
					int mhp=-1;
					mhp = mobinfo[mobs[map][j]->getMobID()].hp;
					MobsPacket::showHP(player, mobid ,mobs[map][j]->getHP()*100/mhp);
					if(mobs[map][j]->getHP() <= 0){
						dieMob(player, mobs[map][j], j);
					}
				break;
				}
			}
		}
	}
	if (skillid == 1111003 || skillid == 1111004 || skillid == 1111005 || skillid == 1111006){ // combo finishing moves
		Skills::clearCombo(player);
	}
	else if(totaldmg > 0){ // only add orbs if did any damage
		Skills::addCombo(player, 1);
	}
}

EDIT: Now includes the check to see if combo attack is active before adding orbs.

EDIT #2: Now includes the minor tweaks to make it more like real MS.
 
Last edited:
Junior Spellweaver
Joined
Apr 14, 2008
Messages
100
Reaction score
0
Going to sleep, any problems I'll reply in the morning.
 
Newbie Spellweaver
Joined
Apr 14, 2008
Messages
10
Reaction score
0
Thank you so much!
Compiled on first try.
Will now test and edit post.
;]
 
Junior Spellweaver
Joined
Apr 14, 2008
Messages
100
Reaction score
0
Oops I think forgot a check to see if combo attack is active before adding orbs, oh well fix it tomorrow.
 
Junior Spellweaver
Joined
Apr 9, 2008
Messages
188
Reaction score
0
I did mines a different way. It only works 99%. Why? Because you can only use it a Few times before it stops working again >_< Dam it.

I try yours later
 
Junior Spellweaver
Joined
Apr 14, 2008
Messages
100
Reaction score
0
If you have already added my original code, here is the check to see if Combo Attack is active before adding orbs.

This is all in Skills.cpp

Add class SkillTimer (it's at the top)
PHP:
	bool skillActive (Player* player, char* name){
		bool active = false;
		for(unsigned int i=0; i<timers.size(); i++){
			if(player == timers[i].player && strcmp(timers[i].name, name) == 0)	active = true;
		}
		return active;
	}

Replace the old Skills::addCombo with this one
PHP:
void Skills::addCombo(Player* player, int hits){ // add combo orbs
	if(timer->skillActive(player, "end1111002")){
		if(player->getCombo()<0) player->setCombo(0);
		for(int i=0; i<hits; i++){
			player->setCombo(player->getCombo()+1);
			if(player->skills->getSkillLevel(1120003)>0 && rand()%100<30+player->skills->getSkillLevel(1120003))
				player->setCombo(player->getCombo()+1); // 4th job skill gives chance to add second orb
		}
		if(player->skills->getSkillLevel(1120003)>0){
			if(player->getCombo()>skills[1120003][player->skills->getSkillLevel(1120003)].x)
				player->setCombo(skills[1120003][player->skills->getSkillLevel(1120003)].x);
		}
		else if(player->getCombo()>skills[1111002][player->skills->getSkillLevel(1111002)].x)
			player->setCombo(skills[1111002][player->skills->getSkillLevel(1111002)].x);
		SkillsPacket::showCombo(player, Maps::info[player->getMap()].Players, skills[1111002][player->skills->getSkillLevel(1111002)].time*1000);
	}
}
 
Junior Spellweaver
Joined
Apr 14, 2008
Messages
100
Reaction score
0
btw running around w/ 10 orbs / sp / and triple throw is insane damage O_O
 
Newbie Spellweaver
Joined
Apr 10, 2008
Messages
38
Reaction score
1
Added + Checked = Works perfectly fine!

For once, I truely thank you for adding this. I couldn't think of a reason why my Combo's don't work; but heres a sweet script. Anyways; thanks alot.

Just an offtopic question;
have you also coded Magic Guard?
 
Junior Spellweaver
Joined
Apr 14, 2008
Messages
100
Reaction score
0
Added + Checked = Works perfectly fine!

For once, I truely thank you for adding this. I couldn't think of a reason why my Combo's don't work; but heres a sweet script. Anyways; thanks alot.

Just an offtopic question;
have you also coded Magic Guard?

magic skills aren't high on my priorities list =P
besides the important ones are working anyway
other than the fact that the magic attack caps at 1999
but it can be uncapped thru hex editing the client if you know where to look
 
Initiate Mage
Joined
Apr 14, 2008
Messages
3
Reaction score
0
I get this error when compiling:
1>.\Skills.cpp(329) : warning C4305: 'argument' : truncation from 'int' to 'bool'
1>.\Skills.cpp(701) : warning C4305: 'argument' : truncation from 'int' to 'bool'

Plz help me? :D
 
Status
Not open for further replies.
Back
Top