|
楼主 |
发表于 2009-8-11 18:32:26
|
显示全部楼层
下面这个就是整个弹幕函数+HashSystem的结构主体~~~
弹幕函数的调用方法
//函数最终会返回一个单位,能用变量记录
//call CreateBullet(玩家,弹幕单位id,X坐标, Y坐标,方向, 速度,距离,伤害数值,伤害检查范围,是否可伤害同伴,是否碰撞可破坏物,碰撞可破坏物范围,是否检查地形可通行)
//最大支持弹幕数量:1000
[jass]
globals
//FCS HashSystem变量声明
integer array udg_HashSystem_Handle //目录
integer array udg_HashSystem_HandleData //内容
boolean array udg_HashSystem_HandleFullBoolean //目录是否为空
//FCS 弹幕函数变量声明
boolean udg_Bullet_DestroyRectBoolean
boolean array udg_Bullet_UnitEmptyBoolean
boolean array udg_Bullet_DamageBoolean
boolean array udg_Bullet_DestroyBoolean
boolean array udg_Bullet_WalkBilityBoolean
unit array udg_Bullet_Unit
real array udg_Bullet_Speed
real array udg_Bullet_Distance
real array udg_Bullet_DistanceMax
real array udg_Bullet_Damage
real array udg_Bullet_DamageArena
rect array udg_Bullet_Rect
endglobals
function H2I takes handle h returns integer
return h
return 0
endfunction
function I2U takes integer i returns unit
return i
return null
endfunction
//FCS HashSystem函数主体开始
function Mod takes integer X, integer Y returns integer
local integer modulus = X - (X / Y) * Y
if (modulus < 0) then
set modulus = modulus + Y
endif
return modulus
endfunction
//call FlushHashSystemMission(H2I(Timer))
function FlushHashSystemMission takes integer DataHandle returns nothing
local integer Handle = Mod(DataHandle, 9)
local integer N = 0
loop
exitwhen udg_HashSystem_Handle[Handle+(N*10)] == DataHandle
set N = N+1
endloop
set Handle = Handle+(N*10)
//call BJDebugMsg("清除取得handle:"+I2S(Handle))
set udg_HashSystem_HandleFullBoolean[Handle] = false
endfunction
//set Integer Data = GetHashSystemInteger(H2I(Timer))
function GetHashSystemInteger takes integer DataHandle returns integer
local integer Handle = Mod(DataHandle, 9)
local integer N = 0
loop
exitwhen udg_HashSystem_Handle[Handle+(N*10)] == DataHandle
set N = N+1
endloop
set Handle = Handle+(N*10)
//call BJDebugMsg("读取取得handle:"+I2S(Handle))
return udg_HashSystem_HandleData[Handle]
endfunction
//call HashSystemInteger(H2I(Timer), H2I(Data))
function HashSystemInteger takes integer DataHandle, integer Data returns nothing
local integer Handle = Mod(DataHandle, 9)
local integer N = 0
loop
exitwhen udg_HashSystem_HandleFullBoolean[Handle+(N*10)] == false
set N = N+1
if ( N > 800 ) then
set N = 0
endif
endloop
set Handle = Handle+(N*10)
//call BJDebugMsg("存储取得handle:"+I2S(Handle))
set udg_HashSystem_HandleFullBoolean[Handle] = true
set udg_HashSystem_Handle[Handle] = DataHandle
set udg_HashSystem_HandleData[Handle] = Data
endfunction
//FCS HashSystem函数主体结束
function Trig_RectArenaBoolean takes nothing returns nothing
set udg_Bullet_DestroyRectBoolean = false
//call BJDebugMsg( "存在可破坏物" )
endfunction
function Bullet_Action takes nothing returns nothing
local timer Timer = GetExpiredTimer()
//local integer ID = GetStoredInteger(udg_GC, I2S(H2I(Timer)), "ID")
local integer ID = GetHashSystemInteger(H2I(Timer))
local boolean DamageBoolean
local boolean DestroyBoolean
local boolean WalkBilityBoolean
local boolean FinishBoolean = false
local unit Unit = udg_Bullet_Unit[ID]
local real Speed
local real Distance
local real DistanceMax
local real Damage
local real DamageArena
local real X
local real Y
local real Face
local group Group
local unit GroupUnit
local rect RectArena
if ( GetUnitState(Unit, UNIT_STATE_LIFE) > 0 ) then //弹幕是否存活
set Distance = udg_Bullet_Distance[ID]
set DistanceMax = udg_Bullet_DistanceMax[ID]
if ( Distance <= DistanceMax ) then //弹幕是否达到最大距离
set Speed = udg_Bullet_Speed[ID]
set X = GetUnitX(Unit)
set Y = GetUnitY(Unit)
set Face = GetUnitFacing(Unit)
set X = X+Cos(Face*0.01745)*Speed
set Y = Y+Sin(Face*0.01745)*Speed
set udg_Bullet_Distance[ID] = Distance+Speed
set DamageArena = udg_Bullet_DamageArena[ID]
//选取弹幕周围单位
set Group = CreateGroup()
call GroupEnumUnitsInRange(Group, X, Y, DamageArena,null)
loop
set GroupUnit = FirstOfGroup(Group)
exitwhen GroupUnit == null
set Damage = udg_Bullet_Damage[ID]
set DamageBoolean = udg_Bullet_DamageBoolean[ID]
if ( DamageBoolean == true ) then //是否伤害同伴
if ( GetUnitState(GroupUnit, UNIT_STATE_LIFE) > 0 ) then
call UnitDamageTarget( Unit, GroupUnit, Damage, true, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
set FinishBoolean = true
//call BJDebugMsg( "伤害目标" )
endif
else
if ( IsUnitEnemy(GroupUnit, GetOwningPlayer(Unit)) == true ) then
if ( GetUnitState(GroupUnit, UNIT_STATE_LIFE) > 0 ) then
call UnitDamageTarget( Unit, GroupUnit, Damage, true, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
set FinishBoolean = true
//call BJDebugMsg( "伤害目标" )
endif
endif
endif
call GroupRemoveUnit(Group, GroupUnit)
endloop
call DestroyGroup(Group)
set WalkBilityBoolean = udg_Bullet_WalkBilityBoolean[ID]
if ( WalkBilityBoolean == true ) then //是否检查可通行
if ( IsTerrainPathable(X, Y, PATHING_TYPE_WALKABILITY) == true ) then //坐标位置是否可通行
set FinishBoolean = true
//call BJDebugMsg( "不可通行" )
endif
endif
set DestroyBoolean = udg_Bullet_DestroyBoolean[ID]
if ( DestroyBoolean == true ) then //是否检查碰撞可破坏物
set RectArena = udg_Bullet_Rect[ID]
call MoveRectTo(RectArena, X, Y)
set udg_Bullet_DestroyRectBoolean = true
call EnumDestructablesInRect( RectArena, null, function Trig_RectArenaBoolean )
if ( udg_Bullet_DestroyRectBoolean == false ) then //是否存在可破坏物
set FinishBoolean = true
endif
endif
else
set FinishBoolean = true
//call BJDebugMsg( "达到距离" )
endif
else
set FinishBoolean = true
//call BJDebugMsg( "弹幕消失" )
endif
if ( FinishBoolean == true ) then
//call FlushStoredMission(udg_GC, I2S(H2I(Timer)))
call FlushHashSystemMission(H2I(Timer))
call PauseTimer(Timer)
call DestroyTimer(Timer)
call KillUnit(Unit)
call RemoveRect(RectArena)
set udg_Bullet_UnitEmptyBoolean[ID] = false
else
call SetUnitX(Unit, X)
call SetUnitY(Unit, Y)
endif
set Timer = null
set Unit = null
set Group = null
set GroupUnit = null
set RectArena = null
endfunction
//函数最终会返回一个单位,能用变量记录
//call CreateBullet(玩家,弹幕单位id,X坐标, Y坐标,方向, 速度,距离,伤害数值,伤害检查范围,是否可伤害同伴,是否碰撞可破坏物,碰撞可破坏物范围,是否检查地形可通行)
//最大支持弹幕数量:1000
function CreateBullet takes player UnitPlayer, integer UnitID, real X, real Y, real Face, real Speed, real DistanceMax, real Damage, real DamageArena, boolean DamageBoolean, boolean DestroyBoolean, real DestroyArena, boolean DestroyArenaBoolean returns unit
local unit Unit = CreateUnit(UnitPlayer, UnitID, X, Y, Face)
local timer Timer = CreateTimer()
local integer N = 0
loop
//call BJDebugMsg( "进入循环判断" )
set N = N+1
exitwhen udg_Bullet_UnitEmptyBoolean[N] == false
if ( N == 1000 ) then //这里修改最大弹幕支持数(数值越少函数效率越高)
set N = 0
//call BJDebugMsg( "循环达到1000次" )
endif
endloop
//call BJDebugMsg( "跳出循环" )
//call DisplayTimedTextToPlayer(UnitPlayer,0,0,30,"当前指针:"+I2S(N))
set udg_Bullet_UnitEmptyBoolean[N] = true
set udg_Bullet_Unit[N] = Unit
set udg_Bullet_Speed[N] = Speed
set udg_Bullet_Distance[N] = 0
set udg_Bullet_DistanceMax[N] = DistanceMax
set udg_Bullet_Damage[N] = Damage
set udg_Bullet_DamageArena[N] = DamageArena
set udg_Bullet_DamageBoolean[N] = DamageBoolean
set udg_Bullet_DestroyBoolean[N] = DestroyBoolean
set udg_Bullet_WalkBilityBoolean[N] = DestroyArenaBoolean
if ( DestroyBoolean == true ) then
set udg_Bullet_Rect[N] = Rect(X-DestroyArena, Y-DestroyArena, X+DestroyArena, Y+DestroyArena)
endif
//call BJDebugMsg( "变量赋值完成" )
//call StoreInteger(udg_GC, I2S(H2I(Timer)), "ID", N)
call HashSystemInteger(H2I(Timer), N)
//call BJDebugMsg( "缓存赋值完成" )
call TimerStart(Timer, 0.01, true, function Bullet_Action)
//call BJDebugMsg( "计时器正常开启" )
set Unit = null
set Timer = null
return udg_Bullet_Unit[N]
endfunction
[/jass] |
|