This script DRASTICALLY needs nerfed (seeing it in action as it is just now could slaughter the top 20 players in about 5-10 seconds. Both damage and hp need reduced before it'll be in a playable state (just now its like 2x dragoon warrior where they need to be killed within a minute of each other))
Code: Select all
-- event_mobs_yinyang_dragons.lua
-- by Stewart Armstrong, 13/08/10
-- YIN-YANG DRAGONS
gYinDead=0 -- Global boolean variable, 0 = false, 1 = true used to signify if the fire dragon is dead
gYangDead=0 -- As above but for the ice dragon
gTimer=0 -- does as it says on the tin, use it as a timer
function yinyang_event_init(m) -- starts the event
yin_init(m) -- set up the fire dragon
mc=spawn_near_id(0x2ae,m.id) -- spawn the ice dragon
yang_init(mc) -- set the stats on the ice dragon
end -- end of function
function yin_init(m)
gTimer=0 -- reset the timer
gYinDead=0 -- just spawned the dragon so its obviously not dead
m:unlearn_spells() -- make it forget all spells
m:learn_spell("ifh") -- teach it flame wind
m:learn_spell("vf") -- teach it fireball
m:set_magic_resistance(4000) -- sets MR to 4000
m:set_name("Yin") -- Sets fire drags name
m:set_align(ALIGN_EVIL) -- Makes it evil
m:set_hp_max(60000) -- gives 60k hp (too much when theres 2 drags)
m:set_intel(5000) -- Gives it 5k int
m.mana = 300 -- sets mana to 300 (making IJO pretty useless!)
m:set_dmg_dice(100) -- melee damage is 100d????
m:set_dmg_sides(3) -- melee damage is 100d3 (100-300 damage per hit)
m:set_thaco(300) -- sets AS to 300 (don't want anyones defense to break it)
m:set_base_ac(40) -- sets it def to 40 (make it tough for people to hit it without a good weapon)
m.immune_to_glassing=true -- self explanatory
m.death_func="yin_dies" -- this function is run when the dragon is killed
m.heartbeat_func="yin_actions" -- heartbeat function, run every second (on top of the base ai so targetting and stuff is all handled)
end -- end fire drag initialising
function yin_dies(m) -- start of death function
local_msg(m,"Yin's flames burn out") -- sends this message out to everyone locally
gYinDead=1 -- sets our global variable to say the fire dragon is dead
if(gYangDead==1) then -- if the ice dragon has already been killed when we kill the fire drag
--m.xp_kill=500000 -- commented out because it's currently breaking things for some reason
x=math.random(1,10) -- pick a number from 1-10 inclusive to pick a weapon
if(x==1) then wep=0x713015 -- Copper Claymore +7 breakdown = 7, the + on the weapon, 1, it's of slaying, 3, copper tint, 015, code for claymore
elseif(x==2) then wep=0x71303c -- Copper +7 labrys
elseif(x==3) then wep=0x7114019 -- Zinc (barbed?) +7 morning star
elseif(x==4) then wep=0x71b018 -- Vampy +7 staff
elseif(x==5) then wep=0x719029 -- Diamond +7 crossbow
elseif(x==6) then wep=0x71c01b -- BR +7 dagger
elseif(x==7) then wep=0x71e03a -- addy +7 katar
elseif(x==8) then wep=0x81d15a -- glass +8 hoe
elseif(x==9) then wep=0x81602a -- silver +8 great maul
elseif(x==10) then wep=0x91703e --gold +9 rondel - deliberately retarded weapon because its a +9
end -- end switch case for weapon choosing
local_msg(m,wep) -- temp debug, should be removed (checking wep had actually been initialised)
wep=set_as_unidentified(wep) -- set it unidentified
map:add_item(m.x,m.y,1,wep,true) -- add it to the map
wep=set_as_unidentified(wep) -- set it unidentified again (i'm not sure why but one of the sample scripts had this, most likely only 1 is needed, not sure if it matters which, kept it in just to avoid having something extra to possibly debug, when I get time will be checked)
update_everyones_fov(m) -- make sure everyone can see the dropped weapon
local_msg(m, "Yin and Yang have been banished from this land!") -- Message to signal the event has ended
end -- end the if for checking the ice drag is dead
end -- end the fire drag death function
function yin_actions(m) -- the fire drags heartbeat function
if(gYangDead==1 and gTimer < 60) then -- if the ice dragon is dead and the timer is at under 60 seconds
gTimer = gTimer + 1 -- add a second to the timer
end
if(gYangDead==1 and gTimer>=60) then -- if the ice drag is dead and the timer is at least at 1 minute (could be == but >= does a bit more error protection)
local_msg(m,"Yang materialises again") -- Send the message to signify the fire drag has been reborn
mc=spawn_near_id(0x2ae,m.id) -- spawns a fire dragon
yang_init(mc) -- sets the spawned fire dragon up like the initial one
end
m:set_health(HN_WOUNDED,0) -- bleed-proof
m:set_health(HN_HEXED,0) -- XJ-proof
m:set_health(HN_HELD,0) -- AEP-proof
if int_rand(25)==1 and m.target_id>=0 then -- on average every 25 seconds
ptr = get_sent_ptr(m.target_id) -- get the target of the dragon
sx=m.x-6 -- startX value for an area damage spell is 6 squares to the left of the dragon
ex=m.x+6 -- endX is 6 squares to the right of the dragon
sy=m.y-6 -- startY is 6 squares above the dragon
ey=m.y+6 -- endY is 6 squares below the dragon
local_msg(m,"Yin launches a tirade of fireballs at his attackers!")
for xx=sx, ex do -- for every x value from sx to ex
for yy=sy, ey do -- for every y value from sy to ey, basically first for loop does a row, second one repeats that row for every row required
ptr=get_sent_ptr_xyz(xx,yy,m.map_level) -- get a reference to that individual square
if((xx~= m.x or yy~=m.y) and ptr~=nil and ptr:get_align()~=m:get_align()) and not ptr:is_dm() then -- this line is pretty much needed or it crashes the server, just checks the the square isn't the 1 the monster is on, the monster is a different alignment from whoever is on that square, and that whoever on the square isn't a DM
spell_fireball("vf",m,ptr,false,0,0,"200d2") -- not sure what the false,0 and 0 params are for, copied from highlord vae example
end -- end the for loop if
end -- end inner for loop
end -- end outer for loop
elseif (int_rand(19)==1) then -- on average every 19 seconds
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ifh"),m.x+1,m.y-1) -- casts flame wind in each direction
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ifh"),m.x+1,m.y) -- note that this doesn't cause any damage
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ifh"),m.x+1,m.y+1) -- damage comes later
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ifh"),m.x,m.y+1)
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ifh"),m.x-1,m.y+1)
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ifh"),m.x-1,m.y)
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ifh"),m.x-1,m.y-1)
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ifh"),m.x,m.y-1)
for xx=m.x-4, m.x+4 do
for yy=m.y-4, m.y+4 do -- another double for loop to go over 4 squares in each direction from the dragon (the range of the wind spells)
ptr=get_sent_ptr_xyz(xx,yy,m.map_level) -- gets reference to the square
if((xx~= m.x or yy~=m.y) and ptr~=nil and ptr:get_align()~=m:get_align()) and not ptr:is_dm() then -- check target is valid
hurt(ptr.id, int_rand(100)+100, "Fire Breath") -- cause 100-200 damage and say "Fire Breath" in local
end -- end if checks
end -- end inner for
end -- end outer for
elseif (int_rand(10)==1) then -- roughly every 10 seconds
spell_fireball("vf",m,tgt,false,0,0,"30d5") -- casts fireball dealing 30-150 damage to single target
end -- end if
end -- end heartbeat function
-- END YIN
function yang_init(m) -- pretty much the same, won't be as much comments here
gTimer=0
gYangDead=0
m:unlearn_spells()
m:learn_spell("ice") -- ice wind
m:learn_spell("aep")
m:learn_spell("vog")
m:set_magic_resistance(4000)
m:set_name("Yang")
m:set_align(ALIGN_EVIL)
m:set_hp_max(100000)
m:set_intel(5000)
m.mana = 300
m:set_dmg_dice(100)
m:set_dmg_sides(3)
m:set_thaco(300)
m:set_base_ac(20)
m.immune_to_glassing=true
m.death_func="yang_dies"
m.heartbeat_func="yang_actions"
end
function yang_dies(m)
local_msg(m,"Yang has melted")
gYangDead=1
if(gYinDead==1) then
-- m.xp_kill=500000
x=math.random(1,10)
if(x==1) then drop=0x1d3c035 -- + 29 str BR tower shield -- here theres 1 more digit in the item code than the weapons, this is because with a single digit values can only go as high as 15, with a 7 digit code we can get higher stat values
elseif(x==2) then drop=0x1d2e090 -- + 29 int addy padded leggins
elseif(x==3) then drop=0x1d20042 -- + 29 int chain coif
elseif(x==4) then drop=0x1d4007a -- + 29 dex amulet -- another example, 1d = 29, 4 = dex, 0 = non-tinted, 07a = code for amulet
elseif(x==5) then drop=0x1e40094 -- + 30 dex gi legs
elseif(x==6) then drop=0x1e30088 -- + 30 str gi torso
elseif(x==7) then drop=0x1f3d072 -- + 31 str glass ring
elseif(x==8) then drop=0x1f2d073 -- + 31 int glass ring
elseif(x==9) then drop=0x1946132 -- + 25 dex silver swampies
elseif(x==10) then drop=0x204c087 -- + 32 BR field plate dex (again a rather stupid drop so it has to be trans'd)
end
local_msg(m,drop) -- another debug because items weren't dropping properly, still a little temperamental, not sure why
drop=set_as_unidentified(drop)
map:add_item(m.x,m.y,1,drop,true)
drop=set_as_unidentified(drop)
update_everyones_fov(m) -- make it visible
local_msg(m, "Yin and Yang have been banished from this land!")
end
end
function yang_actions(m)
if(gYinDead==1 and gTimer < 60) then
gTimer = gTimer + 1
end
if(gYinDead==1 and gTimer>=60) then
local_msg(m,"Yin emerges from a burst of flames")
mc=spawn_near_id(0x22c,m.id) -- respawn fire drag
yin_init(mc)
end
m:set_health(HN_WOUNDED,0)
m:set_health(HN_HEXED,0)
m:set_health(HN_HELD,0)
if int_rand(20)==1 and m.target_id>=0 then
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ice"),m.x+1,m.y-1)
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ice"),m.x+1,m.y)
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ice"),m.x+1,m.y+1)
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ice"),m.x,m.y+1) -- casts ice wind in all 8 directions
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ice"),m.x-1,m.y+1)
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ice"),m.x-1,m.y)
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ice"),m.x-1,m.y-1)
simple_send_event(m.id,EVENT_MAGIC,spells:get_spell_id("ice"),m.x,m.y-1)
for xx=m.x-4, m.x+4 do
for yy=m.y-4, m.y+4 do
ptr=get_sent_ptr_xyz(xx,yy,m.map_level)
if((xx~= m.x or yy~=m.y) and ptr~=nil and ptr:get_align()~=m:get_align()) and not ptr:is_dm() then
set_health(ptr.id,HN_HELD, 5)
hurt(ptr.id, int_rand(100)+150, "You are frozen solid by Yang's Ice Breath")
end
end
end
elseif (int_rand(10)==1) then
spell_chain_lightning("vog",m,ptr,false,0,0,"30d6") -- casts vog that bounces between players (like the mage at the bottom of black mountain)
end
end
--
-- END YANG
--END EVENT