Преглед изворни кода

* Fixed client crash when disguised characters die
* Fixed and finished Guild Skills (~90%)
* Fixed Meltdown and Overthrust used together breaking your own weapon
* Updated Weapon Repair
* Fixed sp recovery problem, thanks to OutSider for pointing it out
* Corrected bUnbreakable value in const.txt
* Updated skill_cast_db for Meltdown

git-svn-id: https://svn.code.sf.net/p/rathena/svn/branches/stable@421 54d463be-8e91-2dee-dedb-b68131a5f0ec

celest пре 20 година
родитељ
комит
e06b2aac29
9 измењених фајлова са 116 додато и 59 уклоњено
  1. 9 0
      Changelog.txt
  2. 6 12
      Dev/bugs.txt
  3. 3 0
      db/Changelog.txt
  4. 2 2
      db/const.txt
  5. 1 1
      db/skill_cast_db.txt
  6. 28 23
      src/map/battle.c
  7. 1 1
      src/map/map.h
  8. 20 8
      src/map/pc.c
  9. 46 12
      src/map/skill.c

+ 9 - 0
Changelog.txt

@@ -1,4 +1,13 @@
 Date	Added
+11/30
+        * Fixed client crash when disguised characters die [celest]
+        * Skill Updates [celest]
+          - Fixed and finished Guild Skills (~90%)
+          - Fixed Meltdown and Overthrust used together breaking your own weapon
+          - Updated Weapon Repair :- uses different materials depending on repaired item
+            (Iron Ore/Iron/Steel/Rough Oridecon)
+          - Fixed sp recovery problem, thanks to OutSider for pointing it out
+
 11/29
 	* Fixed crash in src/char_sql/char.c when setting chars offline [MouseJstr]
 	* Added mapbug.txt which is displayed in map-server, displays

+ 6 - 12
Dev/bugs.txt

@@ -1,6 +1,7 @@
 Problem:	Adding the new guild skills causes it to crash?
-Assigned:	N/A
-Progess:	0%
+Assigned:	Celest
+Progess:	90%
+Note:           The skills should be almost working now.
 
 Problem:	2-2-1 classes are regarded as Novicies by the game server. NPCs aren't taking them as thier jobs but if you the the NPC to do something for a novice class it works with the 2-2-1 like renters. Also if some one becomes high novice, if they use jobra they can become first jobs like a swordsman.
 Assigned:	N/A
@@ -55,25 +56,17 @@ Problem:	When athena is run in linux it creates core files which takes 300 megs.
 Assigned:	N/A
 Progess:	0%
 
-Problem:	The skill tree's max skill lvl is not read/used.
-Assigned:	Celest
-Progess:	~100% (Notes: Maybe there's a less messy way? xP)
-
 Problem:	Char server and Map server crash when you recall some one.
 Assigned:	N/A
 Progess:	0% 
 
-Problem:	Monk's Skill ROOT instantly reboots server
-Assigned:	Celest
-Progess:	100%? (Notes: Typo... my bad, sorry ^^; )
-
 Problem:	Sage's Area Skills (Delu.,Vulcano, etc) if casted on the same area (or overlap each other) instantly reboots server. use @gvgon when test. Don't test it towns
 Assigned:	N/A
 Progess:	0%
 
 Problem:	@disguise has no death sprite so the client crashes when you die, a solution would be that upon death before the sprites change you're undisguised.
-Assigned:	N/a
-Progess:	0%
+Assigned:	Celest
+Progess:	100%
 Note 1:		Please state which sprite makes the client crash, I tried many spriters and I never crashed. [MC Cameri]
 
 Problem:        Changing email and Broadcast both use the same packets / Packet 0x3000 assigned to changing email instead of broadcasting?
@@ -84,6 +77,7 @@ Progress:       0%
 Problem:	Sanctuary heal emp during WoE?
 Assigned:       N/A
 Progress:       0%
+Note:           Isn't sanctuary supposed to be able to heal the emperium? [celest]
 
 Problem:	AFM Maps not loading coords correctly, players appearing outside boundaries of the maps.
 Assigned:	N/A

+ 3 - 0
db/Changelog.txt

@@ -5,6 +5,9 @@
 	Ayathoya items == Added but no effect ( all are "ect" itens)
 	Skill databases == celest working on them i believe.
 
+11/30   * Corrected bUnbreakable value in const.txt [celest]
+        * updated skill_cast_db for Meltdown [celest]
+
 11/29   * Updated skill_db for Quagmire, Fog Wall [celest]
 
 11/28	* Fixed Wedding rings placement 2->136 [Lupus]

+ 2 - 2
db/const.txt

@@ -131,8 +131,8 @@ bFlee		50
 bFlee2		51
 bCritical	52
 bAspd		53
-bFame		57
-bUnbreakable	58
+bFame		59
+bUnbreakable	60
 
 bAtkRange	1000
 bAtkEle		1001

+ 1 - 1
db/skill_cast_db.txt

@@ -246,7 +246,7 @@
 381,1000,1200,0,0,0	//SN_FALCONASSAULT
 382,2000,0,0,0	//SN_SHARPSHOOTING
 383,2000:2400:2800:3200:3600:4000:4400:4800:5200:5600,0,65000:80000:95000:110000:125000:140000:155000:170000:185000:200000,0	//SN_WINDWALK#ウインドウォーク#
-384,5000:5000:6000:6000:7000:7000:8000:8000:9000:10000,0,15000:20000:25000:30000:35000:40000:45000:50000:55000:60000,0	//WS_MELTDOWN#メルトダウン#
+384,5000:5000:6000:6000:7000:7000:8000:8000:9000:10000,0,15000:20000:25000:30000:35000:40000:45000:50000:55000:60000,5000	//WS_MELTDOWN#メルトダウン#
 
 387,0,0,60000,0	//WS_CARTBOOST#カートブースト#
 389,0,0,10000,0 //ST_CHASEWALK

+ 28 - 23
src/map/battle.c

@@ -640,7 +640,7 @@ int battle_get_atk2(struct block_list *bl)
 			if(sc_data[SC_NIBELUNGEN].timer!=-1 && (battle_get_element(bl)/10) >= 8 )
 				atk2 += sc_data[SC_NIBELUNGEN].val2;
 			if(sc_data[SC_STRIPWEAPON].timer!=-1)
-				atk2 = atk2*90/100;
+				atk2 = atk2*sc_data[SC_STRIPWEAPON].val2/100;
 			if(sc_data[SC_CONCENTRATION].timer!=-1) //コンセントレーション
 				atk2 += atk2*(5*sc_data[SC_CONCENTRATION].val1)/100;
 		}
@@ -767,7 +767,7 @@ int battle_get_def(struct block_list *bl)
 				def = def*75/100;
 			//ストリップシールド時は減算
 			if(sc_data[SC_STRIPSHIELD].timer!=-1 && bl->type != BL_PC)
-				def = def*85/100;
+				def = def*sc_data[SC_STRIPSHIELD].val2/100;
 			//シグナムクルシス時は減算
 			if(sc_data[SC_SIGNUMCRUCIS].timer!=-1 && bl->type != BL_PC)
 				def = def * (100 - sc_data[SC_SIGNUMCRUCIS].val2)/100;
@@ -3959,33 +3959,38 @@ struct Damage battle_calc_weapon_attack(
 
 	if(battle_config.equipment_breaking && src->type==BL_PC && (wd.damage > 0 || wd.damage2 > 0)) {
 		struct map_session_data *sd=(struct map_session_data *)src;
-		int breakrate=1;
-		if(sd->status.weapon && sd->status.weapon!=11) {
-			if(target->type == BL_PC && sd->sc_data[SC_MELTDOWN].timer!=-1){ 
-				breakrate+=100*sd->sc_data[SC_MELTDOWN].val1;
-				if(rand()%10000 < breakrate*battle_config.equipment_break_rate/100 || breakrate >= 10000)
-					pc_breakweapon((struct map_session_data *)target);
+		int breakrate = 0;
+
+		if(sd->status.weapon && sd->status.weapon != 11) {
+			if(sd->sc_data[SC_MELTDOWN].timer!=-1) {
+//				breakrate += 100*sd->sc_data[SC_MELTDOWN].val1; // since we don't know if there are any other factors for breaking yet, [celest]
+				breakrate += 100*sd->sc_data[SC_MELTDOWN].val1;
+				if(rand()%10000 < breakrate*battle_config.equipment_break_rate/100 || breakrate >= 10000) {
+					if (target->type == BL_PC)
+						pc_breakweapon((struct map_session_data *)target);
+					else
+						skill_status_change_start(target,SC_STRIPWEAPON,1,75,0,0,skill_get_time2(WS_MELTDOWN,1),0 );
+				}
+
+				breakrate = 70*sd->sc_data[SC_MELTDOWN].val1;
+				if (rand()%10000 < breakrate*battle_config.equipment_break_rate/100 || breakrate >= 10000) {
+					if (target->type == BL_PC)
+						pc_breakarmor((struct map_session_data *)target);
+					else
+						skill_status_change_start(target,SC_STRIPSHIELD,1,75,0,0,skill_get_time2(WS_MELTDOWN,1),0 );
+				}
 			}
-			if(sd->sc_data[SC_OVERTHRUST].timer!=-1)
-				breakrate+=20*sd->sc_data[SC_OVERTHRUST].val1;
+			if(sd->sc_data[SC_OVERTHRUST].timer!=-1) {
+				breakrate = 20*sd->sc_data[SC_OVERTHRUST].val1;
 			//if(wd.type==0x0a) //removed! because CRITS don't affect on breaking chance [Lupus]
 			//	breakrate*=2;
-			if(rand()%10000 < breakrate*battle_config.equipment_break_rate/100 || breakrate >= 10000) {
-				if(pc_breakweapon(sd)==1)
-					wd = battle_calc_pc_weapon_attack(src,target,skill_num,skill_lv,wflag);
+				if(rand()%10000 < breakrate*battle_config.equipment_break_rate/100 || breakrate >= 10000) {
+					if(pc_breakweapon(sd)==1)
+						wd = battle_calc_pc_weapon_attack(src,target,skill_num,skill_lv,wflag);
+				}
 			}
 		}
 	}
-		
-	if (battle_config.equipment_breaking && target->type == BL_PC && (wd.damage > 0 || wd.damage2 > 0)) {
-		int breakrate=1;
-		if(src->type==BL_PC && ((struct map_session_data *)src)->sc_data[SC_MELTDOWN].timer!=-1) breakrate+=70*((struct map_session_data *)src)->sc_data[SC_MELTDOWN].val1;
-		//if (wd.type==0x0a) removed! because CRITS don't affect on breaking chance [Lupus]
-		//	breakrate*=2;
-		if (rand()%10000 < breakrate*battle_config.equipment_break_rate/100 || breakrate >= 10000) {
-			pc_breakarmor((struct map_session_data *)target);
-		}
-	}
 
 	return wd;
 }

+ 1 - 1
src/map/map.h

@@ -556,7 +556,7 @@ enum {
 	SP_USTR,SP_UAGI,SP_UVIT,SP_UINT,SP_UDEX,SP_ULUK,SP_26,SP_27,	// 32-39
 	SP_28,SP_ATK1,SP_ATK2,SP_MATK1,SP_MATK2,SP_DEF1,SP_DEF2,SP_MDEF1,	// 40-47
 	SP_MDEF2,SP_HIT,SP_FLEE1,SP_FLEE2,SP_CRITICAL,SP_ASPD,SP_36,SP_JOBLEVEL,	// 48-55
-	SP_UPPER,SP_PARTNER,SP_CART,SP_FAME,SP_UNBREAKABLE,	//56-58
+	SP_UPPER,SP_PARTNER,SP_CART,SP_FAME,SP_UNBREAKABLE,	//56-60
 	SP_CARTINFO=99,	// 99
 
 	SP_BASEJOB=119,	// 100+19 - celest

+ 20 - 8
src/map/pc.c

@@ -1,4 +1,4 @@
-// $Id: pc.c 101 2004-11-26 5:47:29 PM Celestia $
+// $Id: pc.c 101 2004-11-30 8:27:10 PM Celestia $
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -3462,18 +3462,29 @@ int pc_item_identify(struct map_session_data *sd,int idx)
  */
 int pc_item_repair(struct map_session_data *sd,int idx)
 {
-	int flag=1;
+	int flag=1, material;
+	int materials[5] = { 0, 1002, 998, 999, 756 };
 
 	nullpo_retr(0, sd);
+	struct item *item = &sd->status.inventory[idx];
 
 	if(idx >= 0 && idx < MAX_INVENTORY) {
-		if(sd->status.inventory[idx].nameid > 0 && sd->status.inventory[idx].attribute == 1 ) {
+		if(item->nameid > 0 && item->attribute == 1 ) {
+			if (itemdb_type(item->nameid)==4)
+				material = materials [itemdb_wlv (item->nameid)];
+			else
+				material = materials [3];
+
+			if (pc_search_inventory(sd, material) < 0 ) { //fixed by Lupus (item pos can be = 0!)
+				clif_skill_fail(sd,sd->skillid,0,0);
+				return 0;
+			}
 			flag=0;
-			sd->status.inventory[idx].attribute=0;
+			item->attribute=0;
 			//Temporary Weapon Repair code [DracoRPG]
-			pc_delitem(sd, pc_search_inventory(sd, 999), 1, 0);
+			pc_delitem(sd, pc_search_inventory(sd, material), 1, 0);
 			clif_equiplist(sd);
-			clif_produceeffect(sd, 0, sd->status.inventory[idx].nameid);
+			clif_produceeffect(sd, 0, item->nameid);
 			clif_misceffect(&sd->bl, 3);
 			clif_displaymessage(sd->fd,"Item has been repaired.");
 		}
@@ -5353,7 +5364,7 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage)
 		return 0;
 	}
 	sd->status.hp = 0;
-	pc_setdead(sd);
+	//pc_setdead(sd);
 	if(sd->vender_id)
 		vending_closevending(sd);
 
@@ -5369,6 +5380,7 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage)
 	pc_stop_walking(sd,0);
 	skill_castcancel(&sd->bl,0);	// 詠唱の中止
 	clif_clearchar_area(&sd->bl,1);
+	pc_setdead(sd);
 	skill_unit_out_all(&sd->bl,gettick(),1);
 	if(sd->sc_data[SC_BLADESTOP].timer!=-1)//白刃は事前に解除
 		skill_status_change_end(&sd->bl,SC_BLADESTOP,-1);
@@ -7219,7 +7231,7 @@ static int pc_natural_heal_sp(struct map_session_data *sd)
 	bsp=sd->status.sp;
 
 	inc_num = pc_spheal(sd);
-	if(sd->sc_count && sd->sc_data[SC_EXPLOSIONSPIRITS].timer == -1)
+	if(sd->sc_data[SC_EXPLOSIONSPIRITS].timer == -1)
 		sd->sp_sub += inc_num;
 	if(sd->walktimer == -1)
 		sd->inchealsptick += natural_heal_diff_tick;

+ 46 - 12
src/map/skill.c

@@ -1,4 +1,4 @@
-// $Id: skill.c,v 1.8 2004/11/26 7:12:23 PM Celestia Exp $
+// $Id: skill.c,v 1.8 2004/11/30 8:26:49 PM Celestia Exp $
 /* スキル?係 */
 
 #include <stdio.h>
@@ -24,6 +24,7 @@
 #include "log.h"
 #include "chrif.h"
 #include "guild.h"
+#include "showmsg.h"
 
 #ifdef MEMWATCH
 #include "memwatch.h"
@@ -398,6 +399,10 @@ const struct skill_name_db skill_names[] = {
  { DC_SERVICEFORYOU, "SERVICEFORYOU", "Prostitute" } ,
  { DC_THROWARROW, "THROWARROW", "Throw_Arrow" } ,
  { DC_UGLYDANCE, "UGLYDANCE", "Ugly_Dance" } ,
+ { GD_BATTLEORDER, "BATTLEORDER", "Battle_Orders" } ,
+ { GD_REGENERATION, "REGENERATION", "Regeneration" } ,
+ { GD_RESTORE, "RESTORE", "Restore" } ,
+ { GD_EMERGENCYCALL, "EMERGENCYCALL", "Emergency_Call" } ,
  { HP_ASSUMPTIO, "ASSUMPTIO", "Assumptio" } ,
  { HP_BASILICA, "BASILICA", "Basilica" } ,
  { HP_MEDITATIO, "MEDITATIO", "Meditation" } ,
@@ -832,6 +837,10 @@ int	skill_get_castnodex( int id ,int lv ){
 	if (id >= 10000 && id < 10015) id-= 9500;
 	return (lv <= 0) ? 0:skill_db[id].castnodex[lv-1];
 }
+int	skill_get_nocast ( int id ){
+	if (id >= 10000 && id < 10015) id-= 9500;
+	return skill_db[id].nocast;
+}
 int skill_tree_get_max(int id, int b_class){
 	struct pc_base_job s_class = pc_calc_base_job(b_class);
 	int i, skillid;
@@ -861,15 +870,15 @@ int skillnotok(int skillid, struct map_session_data *sd) {
            return 0;  // gm's can do anything damn thing they want
 
 	// Check skill restrictions [Celest]
-	if(!map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.gvg && skill_db[skillid].nocast & 1)
+	if(!map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.gvg && skill_get_nocast (skillid) & 1)
 		return 1;
-	if(map[sd->bl.m].flag.pvp && skill_db[skillid].nocast & 2)
+	if(map[sd->bl.m].flag.pvp && skill_get_nocast (skillid) & 2)
 		return 1;
-	if(map[sd->bl.m].flag.gvg && skill_db[skillid].nocast & 4)
+	if(map[sd->bl.m].flag.gvg && skill_get_nocast (skillid) & 4)
 		return 1;
-	if (agit_flag && skill_db[skillid].nocast & 8)
+	if (agit_flag && skill_get_nocast (skillid) & 8)
 		return 1;
-	if (battle_config.pk_mode && !map[sd->bl.m].flag.nopvp && skill_db[skillid].nocast & 16)
+	if (battle_config.pk_mode && !map[sd->bl.m].flag.nopvp && skill_get_nocast (skillid) & 16)
 		return 1;
 
      switch (skillid) {
@@ -3727,11 +3736,11 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
 	case BS_REPAIRWEAPON:			/* 武器修理 */
 		if(sd) {
 //動作しないのでとりあえずコメントアウト
-			if (pc_search_inventory(sd, 999) < 0 ) { //fixed by Lupus (item pos can be = 0!)
+			/*if (pc_search_inventory(sd, 999) < 0 ) { //fixed by Lupus (item pos can be = 0!)
 				clif_skill_fail(sd,sd->skillid,0,0);
 				map_freeblock_unlock();
 				return 1;
-			}
+			}*/
 			clif_item_repair_list(sd);
 		}
 		break;
@@ -5422,9 +5431,14 @@ struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid,
 	case GD_SOULCOLD:
 	case GD_HAWKEYES:
 		range=2;
-		target=BCT_NOENEMY;
-		limit=600000;
+		target=BCT_ALL;
+		limit=60000;
 		break;
+
+	default:
+		if(battle_config.error_log)
+			printf ("skill_unitsetting: Unknown skill id = %d\n",skillid);
+		return 0;
 	}
 
 	nullpo_retr(NULL, group=skill_initunitgroup(src,count,skillid,skilllv,skill_get_unit_id(skillid,flag&1)));
@@ -9380,8 +9394,12 @@ int skill_status_change_start(struct block_list *bl, int type, int val1, int val
 			val2=10+val1*3;
 			break;
 		case SC_STRIPWEAPON:
+			if (val2==0) val2=90;
+			break;
 		case SC_STRIPSHIELD:
-		case SC_STRIPARMOR:
+			if (val2==0) val2=85;
+			break;
+		case SC_STRIPARMOR:			
 		case SC_STRIPHELM:
 		case SC_CP_WEAPON:
 		case SC_CP_SHIELD:
@@ -10549,7 +10567,21 @@ int skill_unit_timer_sub( struct block_list *bl, va_list ap )
 							map_addflooritem(&item_tmp,1,bl->m,bl->x,bl->y,NULL,NULL,NULL,0);	// ?返還
 						}
 					}
+					skill_delunit(unit);
 				}
+				break;
+
+			case 0xc1:
+			case 0xc2:
+			case 0xc3:
+			case 0xc4:
+				{
+					struct block_list *src=map_id2bl(group->src_id);
+					if (src)
+						group->tick = tick;
+				}
+				break;
+
 			default:
 				skill_delunit(unit);
 		}
@@ -11605,7 +11637,9 @@ int skill_readdb(void)
 		if(split[0]==NULL)
 			continue;
 		i=atoi(split[0]);
-		if(i < 0 || i > MAX_SKILL_DB)
+		if (i>=10000 && i<10015) // for guild skills [Celest]
+			i -= 9500;
+		else if(i<0 || i>MAX_SKILL_DB)
 			continue;
 		skill_db[i].nocast=atoi(split[1]);
 		k++;